This is the third day of my participation in Gwen Challenge
Before you know it, the text challenge has come to the third day. Today, write an application of reflection and annotation
For those unfamiliar with reflection, read Understanding Java Reflection and dynamic Proxies in the JDK
For those unfamiliar with annotations, read understanding Advanced Java features annotations
First of all, this article is only an application of annotations and reflection, and there will be no discussion on Butterknife. The early implementation of Butterknife was also achieved by reflection and annotations. However, as we all know that reflection is very performance costly, Butterknife has changed its scheme, and this will be covered in future articles
1, to achieve the idea of view injection
When we realize a certain function, we must comb the logic first, we can’t start to write the requirements, so the written code is not only not good performance quality, but also often out of some unexpected bugs, so we have to develop a habit of thinking before writing the code!
So the view injection function, it automatically implements findViewById for us
How do we distinguish the View we want to inject from the other properties?
So naturally, we thought about our annotations, and we put a label on our View to say that this is the View that we need to inject
How do I get the injected view information and then execute findViewById
And that’s where we’re going to use our reflection, for those of you unfamiliar with reflection, to get the portal
We can use reflection to get all of the properties of the Activity object, and then we can tell which View we need to inject based on whether or not there’s an annotation that we define on the property, or we can use the annotation to get the ID that we need to inject, and then we can use the findViewById method to get the View instance, Reflection is then used to assign the view instance
2. Specific implementation of the code
The tag we implemented (annotations)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)// applies to properties
public @interface InjectView {
@IdRes int value (a);
}
Copy the code
First of all, the scope of our annotation should be on the attribute, so @target (elementType.field), because we use reflection to implement this function, the annotation life cycle is RUNTIME specific injection
public class InjectUtils {
public static void injectView(Activity activity){
Class<? extends Activity> activityClass=activity.getClass();
// Get all members of this class
Field[] declaareFields=activityClass.getDeclaredFields();
for (Field declareField : declaareFields) {
// Determine whether the attribute is declared by the InjectView annotation
if(declareField.isAnnotationPresent(InjectView.class)){
InjectView injectView=declareField.getAnnotation(InjectView.class);
// Get the id in the annotation
int viewId=injectView.value();
View view=activity.findViewById(viewId);
// Reflection sets the value of the property
declareField.setAccessible(true);// Set the access permission to public
try {
declareField.set(activity,view);// Set view to property
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
Copy the code
GetFields gets all properties whose modifier is public, including the parent class. GetDeclaredFields gets all properties of this object, but not the parent class. You can get the superClass first and then use getDeclaredFields to get the private properties of the parent class and then use the Activity
public class MainActivity extends AppCompatActivity {
@InjectView(R.id.tv_title)
TextView tvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtils.injectView(this);
tvTitle.setText("The forgotten cool Open."); }}Copy the code
Operation effect:
3, summarize
In terms of annotations alone, annotations are pretty simple, but with annotations combined with other technologies, it can be fun, fun, and complicated! Bytecode enhancement, for example, is also a combination of annotations and bytecode technology! So let’s reinforce reflection and annotation with an example of an injected View! Now that I’ve implemented a View injection with annotations and reflection, you can use the same method to inject data after an Intent is passed!