In the Android use Article (iii) MVC pattern mentions a problem:
1) View layer: The general use of XML file interface descriptive narrative, the use of the time can be very convenient to introduce, but with XML written, but also in the Acitvity Declaration and instantiation, a little trouble, consider whether to do a similar annotation to achieve matching, or write a class to get the individual nodes of the XML and then self-encapsulation, of course, this is just an idea, and then realize.
This idea was finally implemented today, using dependency injection IOC annotations to instantiate the controls in the activity.
Let's first popularize the knowledge of the reflection mechanism and annotation mechanism in Java:
The following two articles of the Great God are quoted:
Java Reflection mechanism
Java AnnotationsAfter completion only need: @ViewInject (id=r.id.btn1,click= "Btnclick") TextView btn1; You can complete the instantiation and join? Click events
Basic ideas:
One, public abstract class D3activity extends activity writes a class to inherit activity.
Second, rewrite Setcontentview to implement annotations in this method.
Three, field[] fields = Activity.getclass (). Getdeclaredfields (); Get field properties in activity
Four, field.getannotation (Viewinject.class); Get annotation properties for a field
Five, Field.set (Activity,sourceview.findviewbyid (viewId)); Instantiating a control
Done, the annotations are implemented to instantiate issues with activity and XML files in Android.
It is also possible to implement annotations on the control's event join, in particular
Implemented in three classes:
Implementing the Annotation class:
Annotation classes can inject IDs---corresponding XML IDs, various click events, customizable
@Target (Elementtype.field) @Retention (retentionpolicy.runtime) public @interface d3view {public int id () default 0; Public String Click () Default ""; Public String Longclick () default ""; Public String ItemClick () default ""; Public String Itemlongclick () Default "";}
Rewrite the activity class to instantiate and add events using reflection and annotations:
Public abstract class D3activity extends Activity {
public void Setcontentview (int layoutresid) {Super.setcontentview (LAYOUTRESID); Initinjectedview (this); }
public void Setcontentview (view view, Layoutparams params) {Super.setcontentview (view, params); Initinjectedview (this); }
public void Setcontentview (view view) {Super.setcontentview (view); Initinjectedview (this); }
private void Initinjectedview (activity activity) { initinjectedview (activity, Activity.getwindow () . Getdecorview ()); } private void Initinjectedview (Object activity,view sourceview) { field[] fields = Activity.getclass (). Getdeclaredfields (); //Get field if (Fields!=null & & fields.length>0) { for (Field field:fields) { try { field.setaccessible (TRUE); //Set as accessible if (field.get (activity) = null) continue; d3view D3view = field.getannotation (d3view.class); if (d3view!=null) { int viewId = D3view.id (); if (viewId = = 0) viewid = Getresources (). Getidentifier (Field.getname (), "id", Getpackagename ()); if ( ViewId = = 0) log.e ("D3activity", "field" + field.getname () + "not Found"); //key, annotation initialization, equivalent to BACKBTN = (TextView) Findviewbyid (R.ID.BACK_BTN); field.set (activity, Sourceview.findviewbyid (viewId)); //Events Setlistener (Activity,field,d3view.click (), Method.click); setlistener (Activity,field,d3view.longclick (), Method.longclick); setlistener (Activity,field,d3view.itemclick (), Method.itemclick); Setlistener (Activity,field,d3view.itemlongclick (), Method.itemlongclick); } } catch (ExCeption e) { e.printstacktrace (); } } } } private void Setlistener (Object activity,field field,string methodname,method Method) Throws Exception{ if (MethodName = = NULL | | Methodname.trim (). Length () = = 0) return; object obj = field.get (activity), switch (method) { case Click: if (obj instanceof view) { ((View) obj). Setonclicklistener (activity) eventlistener. Click (methodName)); } break; case itemclick: if (obj instanceof AbsListView) { (Abslistview) obj. Setonitemclicklistener (new EventListener (activity). ItemClick (MethodName)); } break; case LongClick:  IF (obJ instanceof View) { (view) obj. Setonlongclicklistener (new EventListener (activity). Longclick (MethodName)); } break; case Itemlongclick: if (obj instanceof Abslistview) { ((AbsListView ). Setonitemlongclicklistener (new EventListener (activity). Itemlongclick (methodName)); } break; default: break; } } public enum method{ click,longclick,itemclick,itemlongclick } }
Event class: Implements Onclicklistener, Onlongclicklistener, Onitemclicklistener,onitemlongclicklistener, and can expand itself
public class EventListener implements Onclicklistener, Onlongclicklistener, Onitemclicklistener, Onitemlongclicklistener {private Object handler;private string Clickmethod;private string longclickmethod;private String Itemclickmethod;private string Itemlongclickmehtod;public eventlistener (Object handler) {This.handler = handler ;} Public EventListener Click (String method) {This.clickmethod = Method;return this;} Public EventListener Longclick (String method) {This.longclickmethod = Method;return this;} Public EventListener Itemlongclick (String method) {This.itemlongclickmehtod = Method;return this;} Public EventListener ItemClick (String method) {This.itemclickmethod = Method;return this;} public boolean Onlongclick (View v) {return invokelongclickmethod (handler,longclickmethod,v);} public boolean Onitemlongclick (adapterview<?> arg0, View arg1, int arg2,long arg3) {return Invokeitemlongclickmethod (HANDLER,ITEMLONGCLICKMEHTOD,ARG0,ARG1,ARG2,ARG3);} public void Onitemclick (adapterview<?> arg0, View arg1, int arg2, long arg3) {Invokeitemclickmethod (HANDLER,ITEMCLICKMETHOD,ARG0,ARG1,ARG2,ARG3);} public void OnClick (View v) {Invokeclickmethod (handler, Clickmethod, v);} Private static Object Invokeclickmethod (object handler, String methodName, Object ... params) {if (handler = = null) return n Ull Method = Null;try{method = Handler.getclass (). Getdeclaredmethod (Methodname,view.class); if (method!=null) Return Method.invoke (handler, params); Elsethrow new RuntimeException ("No Such method:" +methodname);} catch (Exception e) {e.printstacktrace ();} return null;} private static Boolean Invokelongclickmethod (object handler, String methodName, Object ... params) {if (handler = = null) ret Urn false; Method = null;try{//public boolean onlongclick (View v) method = Handler.getclass (). Getdeclaredmethod (MethodName, View.class); if (method!=null) {Object obj = Method.invoke (handler, params); return obj==null?false:boolean.valueof ( Obj.tostring ());} Elsethrow New RuntimeException ("No such method:" +MethodName);} catch (Exception e) {e.printstacktrace ();} return false;} Private static Object Invokeitemclickmethod (object handler, String methodName, Object ... params) {if (handler = = null) retu RN null; method = null;try{///onitemclick (adapterview<?> arg0, View arg1, int arg2, long arg3) method = Handler.getc Lass (). Getdeclaredmethod (Methodname,adapterview.class,view.class,int.class,long.class); if (Method!=null) return Method.invoke (handler, params); Elsethrow new RuntimeException ("No Such method:" +methodname);} catch (Exception e) {e.printstacktrace ();} return null;} private static Boolean Invokeitemlongclickmethod (object handler, String methodName, Object ... params) {if (handler = = null ) throw new RuntimeException ("Invokeitemlongclickmethod:handler is null:"); method = null;try{///onitemlongclick (adapterview<?> arg0, View arg1, int arg2,long arg3) method = Handler.g Etclass (). Getdeclaredmethod (Methodname,adapterview.class,view.class,int.class,long.class); if (method!=null{Object obj = Method.invoke (handler, params); return boolean.valueof (Obj==null?false:boolean.valueof (obj.tostring () ));} Elsethrow New RuntimeException ("No Such method:" +methodname); catch (Exception e) {e.printstacktrace ();} return false;}}
This is the end of the way, just need to instantiate:
public class Mainactivity extends D3activity { //@ViewInject EditText input; ID and attribute name also, self-actively match @viewinject (id = r.id.input) EditText EditText; @ViewInject (click= "Btnclick") TextView btn1,btn2,btn3; public void OnCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); } public void Btnclick (View v) { switch (V.getid ()) {Case R.id.btn1:btn1.settext (Edittext.gettext (). toString ()); Toast.maketext (Getapplicationcontext (), "111", Toast.length_short). Show (); Break;case R.id.btn2:toast.maketext ( Getapplicationcontext (), "222", Toast.length_short). Show (); Break;case R.id.btn3:toast.maketext ( Getapplicationcontext (), "333", Toast.length_short). Show (); break;default:break;}}}
The corresponding XML layout file:
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "Android:layout_width=" Fill_parent "android:layout_height=" fill_parent "android:orientation=" vertical "&G T <edittext android:id= "@+id/input" android:layout_width= "fill_parent" android:layout_height= "Wrap_ Content "/> <textview android:id=" @+id/btn1 "android:layout_margintop=" 10DP " Android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" android:text= "Set Yourself"/>&L T TextView android:id= "@+id/btn2" android:layout_margintop= "10DP" android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" android:text= "btn2"/><textview android:id= "@+id/btn3" android:layout_margintop= "10DP" android:layout_width= "wrap_content" android:layout_height= "Wrap_cont Ent "Android:text= "Btn3"/></linearlayout>
The source code has been placed on GitHub, interested to be able to look at: https://github.com/mozhenhau/injectAndroid.git
Android use chapter (iv) Annotation Dependency injection IOC implementation bound control