Android annotation binding control

Source: Internet
Author: User

Android annotation binding control

In Android development, there is a love and hate method called findViewById (int). I think if you are an Android developer, you must know this method, let's take a look at how the KJFrameForAndroid framework solves this problem.

KJFrameForAndroid framework project address: https://github.com/kymjs/kjframeforandroid.

Why does findViewById (int) make people love and hate it? I think everyone is also very touched.
Writing a layout using Java code and writing an xml file is completely incomparable. Xml layout is too convenient.
Similarly, if you want to get the object of a control, if you are using the layout written in the xml layout file, you must call the findViewById () method.

 
 
  1. TextView t = (TextView) findViewById(R.id.x); 

This is the most common process of retrieving a textview object in the xml layout.
So the question is, it's too long to name this amazing Method !!! Well, there are no mistakes in people's names. to clearly describe the meaning of this function, there must be so many letters.
However, it is too troublesome for me to return a View. I have a total of 100 Eclipse default lines of code in one line.) The indent eight lattice method is written in the class, and the statement is written in the method ),
Even if the textView object in the preceding example has only one letter and the id has only one letter, this initialization will occupy 54 of my columns. If the variable name is longer and the indentation level is deeper, the initialization will be two rows.
There are at least four controls on an interface. Such complicated Initialization is too boring.
There will always be corresponding solutions to problems. Next I will introduce you to solve this problem using annotations.
Note:

Java provides the annotation function starting with jdk1.5, allowing developers to define and use their own annotation types. This function consists of a syntax for defining annotation types and a syntax for describing an annotation declaration, the API for reading the annotation, a class file decorated with the annotation, and an annotation processing tool.
First, you need to accept a keyword @ interface.
@ Interface indicates that we have inherited java. lang. annotation. annotation class. This is an Annotation base class interface, just like an Object class. Now you only need to know its existence.
There is also a rule: when defining annotations, other annotations or interfaces cannot be inherited.
This is the simplest annotation class.

 
 
  1. public @interface MyAnnotation { 
  2.   

However, we usually add two annotations to this annotation class during use:

@ Target (ElementType. FIELD), @ Retention (RetentionPolicy. RUNTIME)
ElementType and RetentionPolicy are two enumeration classes. ElementType. FIELD indicates that we need to annotate a FIELD. The following is an introduction from JDK1.6:

Note:

The following is the definition and usage of the bound control annotation section in the KJFrameForAndroid framework.

 
 
  1. @Target(ElementType.FIELD) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. public @interface BindView { 
  4.     public int id(); 
  5.     public boolean click() default false; 
  6. }
  7. @BindView(id = R.id.x, click = true) 
  8. private TextView t; 

We can see that in addition to significantly reducing the amount of code, it also makes the code structure clearer.
The id () in the definition section indicates that the annotation accepts an int type data as the value corresponding to the id, as shown in id = R. id. xxx );
Similarly, the click of the definition part indicates that a Boolean type of data is accepted as the corresponding value of the click. You can also set a default value to be modified using default;
Processing annotation:

Now that we know how to define and use annotations, we should know how to handle them.
As mentioned above, the bindview annotation can accept an int type value and a Boolean type value. How can we obtain these two values after they are accepted?
In fact, the method for obtaining the object is very simple, that is, calling the object from the two methods defined in the Declaration-> id () or click () method.
Now there is a problem. The annotation type cannot be a new object directly. Where can this BindView object come from?
In this case, the reflection mechanism of Java is used. We know that every class inherited from the Object class will inherit a getClass () method. Let's take a look at the prototype of this method:

 
 
  1. /** 
  2.     * Returns the unique instance of {@link Class} that represents this 
  3.     * object's class. Note that {@code getClass()} is a special case in that it 
  4.     * actually returns {@code Class<? extends Foo>} where {@code Foo} is the 
  5.     * erasure of the type of the expression {@code getClass()} was called upon. 
  6.     * <p> 
  7.     * As an example, the following code actually compiles, although one might 
  8.     * think it shouldn't: 
  9.     * <p> 
  10.     * <pre>{@code 
  11.     *   List<Integer> l = new ArrayList<Integer>(); 
  12.     *   Class<? extends List> c = l.getClass();}</pre> 
  13.     * 
  14.     * @return this object's {@code Class} instance. 
  15.     */ 
  16.    public final native Class<?> getClass(); 

It is a native method. According to the annotation, we know that this method returns the Class object of this Class, and it is also the binary object of this Class.
The getDeclaredFields () method is used to return all fields of the Class. The return type is Field [].
GetAnnotation (Class <?>) of the Field object) Method, we can get the object of any Class, through getAnnotation (Class <?> ), We can get the BindView object.

For example

 
 
  1. Field [] fields = currentClass. getClass (). getDeclaredFields ();
  2. For (int I = 0; I <fields. length; I ++ ){
  3. BindView bindView = field. getAnnotation (BindView. class );
  4. Int viewId = bindView. id (); // This is the id we passed
  5. Boolean clickLis = bindView. click (); // This is the click
  6. }

Applications in Android projects:

So far, we have learned about annotations, how to use them, and how to handle annotations. Now there is only one last question: Use in projects.
It's easy to pass an Activity object and call findViewById.
So we can
Activity. findViewById (bindView. id ());
Finally, we can call this function in our Activity.

The following is the core code for binding controls using annotations in the Android Application Framework KJFrameForAndroid:

 
 
  1. /**
  2. * @ Param currentClass
  3. * Current class, generally Activity or Fragment
  4. * @ Param sourceView
  5. * Direct or indirect parent control of the control to be bound
  6. */
  7. Public static void initBindView (Object currentClass, View sourceView ){
  8. // Obtain all attributes through reflection. The reflected field may be a static class) field or instance Field
  9. Field [] fields = currentClass. getClass (). getDeclaredFields ();
  10. If (fields! = Null & fields. length> 0 ){
  11. For (Field field: fields ){
  12. // Return the BindView type annotation content
  13. BindView bindView = field. getAnnotation (BindView. class );
  14. If (bindView! = Null ){
  15. Int viewId = bindView. id ();
  16. Boolean clickLis = bindView. click ();
  17. Try {
  18. Field. setAccessible (true );
  19. If (clickLis ){
  20. SourceView. findViewById (viewId). setOnClickListener (
  21. (OnClickListener) currentClass );
  22. }
  23. // Assign the field of currentClass to sourceView. findViewById (viewId)
  24. Field. set (currentClass, sourceView. findViewById (viewId ));
  25. } Catch (Exception e ){
  26. E. printStackTrace ();
  27. }
  28. }
  29. }
  30. }
  31. }

In fact, the annotation binding control in Android is also called an IOC control reversal application in Android. In fact, the essence of the use is the use of reflection in Java basics. It is worth mentioning that the reflection execution efficiency is very low.
If not necessary, minimize the use of reflection, because it will greatly drag down the execution efficiency of your application.
By the way, I always reject annotations because class reflection is too inefficient. Currently, there are many Android Application development frameworks, such as KJFrameForAndroid, xUtils, afinal, and thinkAndroid. These frameworks use reflection to bind annotations to controls.
More frameworks and even everything are completed using annotations. I can only say that annotations are convenient, but please use them with caution.

Link: http://my.oschina.net/kymjs/blog/305882

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.