Android annotation-bound controls, not as difficult as you think

Source: Internet
Author: User

Android development, there is a love and hate method called Findviewbyid (int); I think if you are a people Android developer, you must know this method.
So why is it that people love and hate? Presumably everyone is also very touched.
Write a layout, write in Java code and write in XML file, complete speed is completely incomparable. The XML layout is too convenient.
Similarly, to get a control object, if you are using the XML layout file to write the layout, then you must call Findviewbyid () this method.

TextView t = (TextView) Findviewbyid (r.id.x);

This is our most common process of getting an TextView object in an XML layout.
Then the problem is coming, this special wonderful method name is too long!!! Well, in fact, there is no wrong name, to describe the meaning of this function, it must be so many letters.
But it's too much trouble for you to return a view so that I can use it. My line of code is a total of 100 columns (eclipse default), indentation eight (the method is written in the class, the statement is written in the method),
Even if, like the example above, the TextView object has only one letter and the ID has only one letter, this initialization also takes up 54 of my columns. If the name of the variable is longer, the indentation level is deeper, and this one is initialized in two lines.
There are at least four controls on an interface, so complicated to initialize, too much for dad.
There will always be a corresponding solution, I would like to introduce you to the use of annotations to solve this problem.

Understanding Annotations:

Starting with jdk1.5, Java provides annotations that allow developers to define and use their own annotation types, which consists of a syntax for defining annotation types and a syntax for describing an annotation declaration, an API for reading annotations, a class file with annotation adornments, and an annotation processing tool.
First, you need to accept a keyword @interface, oh, it is not an interface definition keyword, not the @interface keyword inside oc, is a keyword in Java that declares an annotation class.
Using @interface means that we have inherited the Java.lang.annotation.Annotation class, which is a base class interface for annotations, just like the object class, now you just need to know it exists.
One more rule: when defining annotations, you cannot inherit other annotations or interfaces.
So, this is the simplest annotation class.

Public @interface Myannotation {}

However, we always add two annotations to this annotation class when we use it:

@Target (Elementtype.field), @Retention (Retentionpolicy.runtime)
ElementType, Retentionpolicy is two enumeration classes, Elementtype.field means that we need to annotate a field, the following is an excerpt from the JDK1.6 Documentation:

Use annotations:

The following is the definition and use of the annotations section of bound controls in the Kjframeforandroid framework:

@Target (Elementtype.field) @Retention (retentionpolicy.runtime) public @interface the bindview {public int id (); public boolean click () default false;}
@BindView (id = r.id.x, click = True) Private TextView t;

We can see that, in addition to significantly reducing the amount of code, it also makes the code structure clearer.
Where the definition part of the ID () indicates that the annotation accepts an int type of data as the value corresponding to the ID (as in the use of id = r.id.xxx);
Similarly, the click of the definition section indicates that a Boolean type of data is accepted as the value of the click, and you can set a default value to use the defaults modifier;

Handling Annotations:

We already know how annotations are defined and used, and then we should know what to do with them. The
has already been said, BindView annotations can accept a value of type int and a Boolean value, then how are these two values accepted for later? The
way to get it is simply to call this object from a BindView type object, from the two method-->id () or the Click () method defined in the declaration.
Now there is a problem, the annotation type is not directly new object, then where does this BindView object come from? The
then needs to use the reflection mechanism of java. We know that every class that inherits from the object class inherits a GetClass () method, and the following is a look at the prototype of this method:

    /**     * returns the unique instance  of {@link  Class} that represents this     *  Object ' s class. note that {@code  getclass ()} is a special case  in that it     * actually returns {@code  class <? extends foo>} where {@code  Foo} is the      * erasure of the type of the expression {@code  getclass ()}  was called upon.     * <p>     *  as an example, the following code actually compiles, although  one might     * think it shouldn ' t:      * <p>     * <pre>{@code      *   List<Integer>  l = new ArrayList<Integer> (     *   class); <? extends list> c = l.getclass ();} </pre>     *     *  @return  this object ' s {@code  Class} instance.     */    public  Final native class<?> getclass ();

is a native method, according to the comment we know that this method returns the class object of the classes and is also the binary object of the class.
There is a method in class called Getdeclaredfields (), which is used to return all fields of this class, the return type is field[]
Through the Field object's Getannotation (class<?>) method, we can get to any Class object, through Getannotation (class<?>), We can get to the object of BindView.

For example:

field[] fields = Currentclass.getclass (). Getdeclaredfields (), for (int i = 0; i < fields.length; i++) {BindView Bindvi        ew = field.getannotation (Bindview.class);  int viewId = Bindview.id (); This is the ID we passed the boolean clicklis = Bindview.click (); This is what we preach click}
Apply to Android projects:

Now that we've learned the annotations, and know how to use them, how to handle annotations, there's only one last question: use in the project.
Very simple, to pass an activity object, call Findviewbyid () not on the line.
So we can do this.
Activity.findviewbyid (Bindview.id ());
Finally, calling this function in our activity is OK.

The following is the core code for using the annotations bound control in the Android app framework Kjframeforandroid:

/**     *  @param  currentClass     *              current class, typically activity or fragment      *  @param  sourceView     *              direct or indirect parent control of the control to be bound      */    public  static void initbindview (Object currentclass, view sourceview)  {         //  get all properties through reflection, the reflected field may be a class (static) field or an instance field          field[] fields = currentclass.getclass (). GetDeclaredFields ();         if  (fields != null && fields.length  > 0)  {            for  ( Field field : fields)  {                //   Returns the annotation content of the BindView type                  bindview bindview = field.getannotation (Bindview.class);                 if  (Bindview != null)  {                     int viewid = bindview.id ();                     boolean clickLis =  Bindview.click ();                     try {                          field.setaccessible (True);                         if   (Clicklis)  {                             sourceview.findviewbyid ( viewId). Setonclicklistener (                                       (Onclicklistener)  currentclass);                         }                          //  currentclass field Assignment to Sourceview.findviewbyid (viewId)                          field.set ( Currentclass, sourceview.findviewbyid (viewId));                     } catch  (exception e)  {                          e.printstacktrace ();                     }                 }             }        }    }

In fact, wirelessly's annotated binding control (also known as an IOC control reversal application in wirelessly) is essentially using the reflection in the Java base. It is worth mentioning that the efficiency of reflection execution is very low
If it is not necessary, you should minimize the use of reflection, as it will greatly hinder the execution efficiency of your application.
Incidentally: I have always rejected annotations because class reflection is too inefficient. There are now many Android application development frameworks, such as Kjframeforandroid, Xutils, afinal, and thinkandroid, which are all using reflection to play the annotation bound control.
The more frameworks and even all things are done using annotations, I can only say that annotations are convenient, but please use with caution.

Android annotation-bound controls, not as difficult as you think

Related Article

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.