Reprint please indicate source: http://blog.csdn.net/lmj623565791/article/details/39269193, this article from: "Zhang Hongyang's Blog"
1. Overview
First we blow the whistle, what is the IOC, the control reversal (inversion of the English abbreviation for IOC), what does that mean?
You need to use a lot of member variables in a class, the traditional way of writing, you want to use these member variables, then you come out with a Bai ~ ~
The IOC principle is: No, we don't want new, so the coupling is too high; you configure an XML file that indicates which class, what member variables are used, and when you wait for the class to load, I'll inject you in.
What good does it do?
Answer this question, just can answer another question, many people ask, the project stratification development is right, divides into the control layer, the business layer, the DAO layer God Horse. Then each layer for the sub to a packet to put the interface, a package to implement it? As long as an implementation package does not ~ Just, if you understand the IOC, you know the role of these interfaces, it does not mean that you do not use new, you just declare the member variable + write a configuration file, someone help you new; At this time, you in the class, you can use the member variables are declared interface, Then you'll find out what you need to do when the implementation class changes, or when you switch the implementation class. You just have to make a simple change in the config file. If you are using a real implementation class, now for the implementation class, you need to find all the declaration of this implementation class, manually modify the class name; If you meet a changeable boss, yes, hehe ~
Of course, many will feel, write a configuration file, a slot, this much trouble. So, there is another solution, you have to idle configuration file trouble, you use annotations it. You add an annotation to the member variable that you need to inject, for example: @Inject, that's all, you can't say a word like that.
Of course, with the configuration files and annotations, then how to inject it? In fact, the string class path into a class, of course, the reflection of the game, say, a long time ago, the reflection is very slow ah, well, it is a long time ago, now is not too slow, of course, certainly not up to the original speed ~ ~ No reflection, no frame.
If you feel the annotations, reflect the good quality of God horse. I say: Just do It, you will find the annotations and you write a common javabean almost; API just a few lines, do not be shocked to live ~
2. Framework Implementation
To get to the point, the Android IOC framework, in fact, is to help you inject all the controls, layout files and so on. If you have used the framework of the Xutils,afinal class, you are certainly not unfamiliar ~
Inject view
Suppose: We're an activity with 10 or so view.
Traditional practice: We need to give this activity to set the layout file, and then in the OnCreate inside a Findviewbyid
Objective: Add a note to the activity class to help us automatically inject the layout arts; When declaring a view, add a line of annotations and automatically help us findviewbyid;
So our target class is this:
@ContentView (value = r.layout.activity_main) public class Mainactivity extends baseactivity{@ViewInject (R.ID.ID_BTN) Private button mBtn1; @ViewInject (r.id.id_btn02) private button mBtn2;
3. Coding
1. Define Annotations
First of all we need two note files:
Package Com.zhy.ioc.view.annotation;import Java.lang.annotation.elementtype;import Java.lang.annotation.Retention ; import Java.lang.annotation.retentionpolicy;import java.lang.annotation.Target; @Target (Elementtype.type) @ Retention (retentionpolicy.runtime) public @interface contentview{int value ();}
Contentview is used on a class and is used primarily to indicate which layout file the activity needs to use.
@ContentView (value = r.layout.activity_main) public class mainactivity
Package Com.zhy.ioc.view.annotation;import Java.lang.annotation.elementtype;import Java.lang.annotation.Retention ; import Java.lang.annotation.retentionpolicy;import java.lang.annotation.Target; @Target (Elementtype.field) @ Retention (retentionpolicy.runtime) public @interface viewinject{int value ();}
Used on member variables to specify the ID of the view
@ViewInject (r.id.id_btn) private Button mBtn1;
Simply say the note: the defined keyword @interface; @Target indicates where the annotation can be used, possible types of type (Class), FIELD (member variable), possible types:
public enum ElementType { /** * Class, interface or enum declaration. */ TYPE, /** * Field declaration. */ FIELD, /** * Method declaration. */METHOD, /** * Parameter declaration. * * PARAMETER, /** * Constructor declaration. */CONSTRUCTOR, /** * Local variable declaration. */ local_variable, /** * Annotation type declaration. */Annotation_type, /** * Package declaration. */Package }
These are the enumerations.
@Retention: Indicates the level at which the annotation information needs to be saved; we set it here as runtime.
Possible types:
public enum Retentionpolicy { /** * Annotation are only available in the source code. */ source, /** * Annotation is available in the source code and in the class file, but not * at runtime. T The is the default policy. */ class, /** * Annotation is available in the source code, the class file and was * available at runtime . */ RUNTIME}
These enumerations ~
2, Mainactivity
Package Com.zhy.zhy_xutils_test;import Android.app.activity;import Android.os.bundle;import Android.view.View; Import Android.view.view.onclicklistener;import Android.widget.button;import Android.widget.toast;import Com.zhy.ioc.view.viewinjectutils;import Com.zhy.ioc.view.annotation.contentview;import Com.zhy.ioc.view.annotation.ViewInject; @ContentView (value = r.layout.activity_main) public class mainactivity Extends Activity implements onclicklistener{@ViewInject (r.id.id_btn) private Button mBtn1; @ViewInject (R.ID.ID_BTN02) Private Button mBtn2; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate) ; Viewinjectutils.inject (This), Mbtn1.setonclicklistener (This), Mbtn2.setonclicklistener (this);} @Overridepublic void OnClick (View v) {switch (V.getid ()) {case R.id.id_btn:toast.maketext (mainactivity.this, Click me? ", Toast.length_short). Show (); Break;case R.id.id_btn02:toast.maketext (Mainactivity.this," I AM sleeping!!! " , Toast.length_short). Show (); BREak;}}}
The annotations are all written, the core code is viewinjectutils.inject (this) ~
3, Viewinjectutils
1, the first is injected into the main layout file code:
/** * Inject main layout file * * @param activity */private static void Injectcontentview (activity activity) {class<? extends Activi Ty> clazz = Activity.getclass ();//whether there are contentview annotations on the query class Contentview Contentview = Clazz.getannotation ( Contentview.class); if (Contentview! = NULL)//exists {int contentviewlayoutid = Contentview.value (); Try{method Method = Clazz . GetMethod (Method_set_contentview,int.class); method.setaccessible (true); Method.invoke (activity, Contentviewlayoutid);} catch (Exception e) {e.printstacktrace ();}}}
Through the incoming activity object, obtains its class type, determines whether writes Contentview this annotation, if writes, reads its value, then obtains Setcontentview this method, uses invoke to make the call;
There is a constant:
private static final String Method_set_contentview = "Setcontentview";
2, Next is to inject views
private static final String method_find_view_by_id = "Findviewbyid";/** * Inject All controls * * @param activity */private Static void Injectviews (activity activity) {class<? extends activity> clazz = Activity.getclass (); field[] fields = Clazz.getdeclaredfields ();//traverse all member variables for (Field field:fields) {viewinject viewinjectannotation = field. Getannotation (Viewinject.class); if (viewinjectannotation! = null) {int viewId = Viewinjectannotation.value (); if ( ViewId! =-1) {LOG.E ("TAG", viewid+ "");//Initialize Viewtry{method Method = Clazz.getmethod (Method_find_view_by_id,int.class) Object Resview = Method.invoke (activity, viewId); field.setaccessible (true); Field.set (activity, Resview);} catch (Exception e) {e.printstacktrace ();}}}}
Get all the properties of the Declaration, traverse, find the attribute that exists viewinject annotation, or its value, then go to call the Findviewbyid method, and finally set the value to field~~~
Well, just write these two methods into the inject.
public static void inject (activity activity) {Injectcontentview (activity); injectviews (activity);}
This article mainly understand how to create such a framework, the next article, will teach you how to inject events, do not write what Setxxxlistener ~ ~ ~
:
SOURCE Click to download
Android advanced teach you to build the IOC framework "Viewinject" (above) in Android