标签:
1、视图
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 > 7 8 <Button 9 android:id="@+id/btn_login" 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" 12 android:text="登陆" /> 13 <Button 14 android:id="@+id/btn_register" 15 android:layout_width="fill_parent" 16 android:layout_height="wrap_content" 17 android:text="注册" /> 18 19 </LinearLayout>
2、MainActivity
1 package com.zyh.zyh_ioc; 2 3 import android.os.Bundle; 4 import android.util.Log; 5 import android.view.View; 6 import android.widget.Button; 7 8 import com.zyh.ioc.annotation.ContentView; 9 import com.zyh.ioc.annotation.OnClick; 10 import com.zyh.ioc.annotation.ViewInject; 11 import com.zyh_ioc.activity.BaseActivity; 12 import android.widget.Toast; 13 14 @ContentView(R.layout.activity_main) 15 public class MainActivity extends BaseActivity { 16 @ViewInject(R.id.btn_login) 17 private Button btnLogin; 18 19 @ViewInject(R.id.btn_register) 20 private Button btnRegister; 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 Log.i("zyh",btnLogin.getText().toString() + "," + btnRegister.getText().toString()); 26 } 27 28 @OnClick({R.id.btn_login,R.id.btn_register}) 29 public void Toast(View btn){ 30 switch(btn.getId()){ 31 case R.id.btn_login: 32 Toast.makeText(this, "登陆", Toast.LENGTH_SHORT).show(); 33 break; 34 case R.id.btn_register: 35 Toast.makeText(this, "注册", Toast.LENGTH_SHORT).show(); 36 break; 37 default: 38 break; 39 } 40 } 41 }
3、BaseActivity
1 package com.zyh_ioc.activity; 2 3 import com.zyh.ioc.utils.InjectUtils; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 8 public class BaseActivity extends Activity { 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 InjectUtils.inject(this); 13 } 14 }
4、InjectUtils
1 package com.zyh.ioc.utils; 2 3 import com.zyh.ioc.annotation.ContentView; 4 import com.zyh.ioc.annotation.EventBase; 5 import com.zyh.ioc.annotation.OnClick; 6 import com.zyh.ioc.annotation.ViewInject; 7 import com.zyh.ioc.proxy.ListenerInvocationHandler; 8 9 import android.app.Activity; 10 import android.view.View; 11 12 import java.lang.annotation.Annotation; 13 import java.lang.reflect.Field; 14 import java.lang.reflect.Method; 15 import java.lang.reflect.Proxy; 16 17 //=============================================== 18 //类的Annotation需要类对象来获取 19 //方法的Annotation需要方法对象来获取 20 //属性的Annotation需要属性对象来获取 21 //Annotation的Annotation需要Annotation的类对象来获取 22 //=============================================== 23 24 public class InjectUtils { 25 public static void inject(Activity activity){ 26 injectContentView(activity); 27 injectViews(activity); 28 injectEvents(activity); 29 } 30 31 /** 32 * @desc 注入布局 33 * @param activity 34 */ 35 private static void injectContentView(Activity activity) { 36 Class<? extends Activity> clazz = activity.getClass(); 37 ContentView contentView = clazz.getAnnotation(ContentView.class); 38 int layoutId = contentView.value(); 39 activity.setContentView(layoutId); 40 } 41 42 /** 43 * @desc 注入控件 44 * @param activity 45 */ 46 private static void injectViews(Activity activity) { 47 Class<? extends Activity> clazz = activity.getClass(); 48 Field[] fields = clazz.getDeclaredFields(); 49 for(Field field : fields){ 50 ViewInject viewInject = field.getAnnotation(ViewInject.class); 51 if(viewInject != null){ 52 //获取注解上的值 53 int viewId = viewInject.value(); 54 Object view = activity.findViewById(viewId);//获取视图对象 55 try { 56 field.setAccessible(true);//表明私有的属性也可以设置值 57 field.set(activity, view);//给属性设值 58 } catch (Exception e) { 59 e.printStackTrace(); 60 } 61 } 62 } 63 } 64 65 /** 66 * @desc 注入事件 67 * @param activity 68 */ 69 private static void injectEvents(Activity activity) { 70 Class<? extends Activity> clazz = activity.getClass(); 71 Method[] methods = clazz.getMethods(); 72 for(Method method : methods){ 73 Annotation[] annotations = method.getAnnotations(); 74 for(Annotation annotation : annotations){ 75 Class<? extends Annotation> annotationType = annotation.annotationType();//返回的是Annotation类对象 76 if(annotationType != null){ 77 EventBase eventBase = annotationType.getAnnotation(EventBase.class);//获取注释的注释 78 if(eventBase != null){ 79 String listenerSetter = eventBase.listenerSetter();//获取的设置监听事件的方法名 80 Class<?> listenerType = eventBase.listenerType();//获取监听事件的类对象 81 String methodName = eventBase.callBackMethod();//获取回调方法名 82 83 //下面两行代码说明:得到Annotation实例就可以获取annotation括号里的内容 84 /*OnClick onClick = (OnClick) annotation; 85 int[] xxx = onClick.value();*/ 86 try { 87 //这里是利用反射获取viewIds的值 88 Method valueMethod = annotationType.getDeclaredMethod("value"); 89 int[] viewIds = (int[]) valueMethod.invoke(annotation, null); 90 91 //设置代理 92 ListenerInvocationHandler handler = new ListenerInvocationHandler(activity); 93 //onClick->toast 94 handler.addMethod(methodName, method); 95 //通过Proxy产生一个listenerType类型的代理对象 96 //listener是一个onClickListener对象 97 Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class<?>[]{listenerType}, handler); 98 99 //多个按钮要注册监听 100 for(int viewId : viewIds){ 101 View view = activity.findViewById(viewId); 102 103 //获取setOnClickListener方法 104 Method setter = view.getClass().getMethod(listenerSetter, listenerType); 105 //注册 106 setter.invoke(view, listener); 107 } 108 } catch (Exception e) { 109 e.printStackTrace(); 110 } 111 } 112 } 113 } 114 } 115 } 116 }
5、自定义的Annotation
1)布局的Annotation
1 package com.zyh.ioc.annotation; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 //指定注解使用的类的位置上 9 @Target(ElementType.TYPE) 10 11 //编译程序将注解存储在class文件中,让虚拟机通过反射读入 12 @Retention(RetentionPolicy.RUNTIME) 13 public @interface ContentView { 14 int value(); 15 }
2)findViewById的Annotation
1 package com.zyh.ioc.annotation; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 //指定使用在属性上 9 @Target(ElementType.FIELD) 10 11 @Retention(RetentionPolicy.RUNTIME) 12 public @interface ViewInject { 13 int value(); 14 }
3)点击事件的Annotation
1 package com.zyh.ioc.annotation; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 import android.view.View; 9 10 @Target(ElementType.METHOD) 11 @Retention(RetentionPolicy.RUNTIME) 12 @EventBase(listenerSetter = "setOnClickListener",listenerType = View.OnClickListener.class,callBackMethod = "onClick") 13 public @interface OnClick { 14 int[] value(); 15 }
1 package com.zyh.ioc.annotation; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 //说明在另外的注解上使用 9 @Target(ElementType.ANNOTATION_TYPE) 10 @Retention(RetentionPolicy.RUNTIME) 11 public @interface EventBase { 12 /** 13 * @desc 例如:setOnClickListener的方法名称 14 * @return 15 */ 16 String listenerSetter(); 17 18 /** 19 * @desc 说明listener的类型 20 * @return 21 */ 22 Class<?> listenerType(); 23 24 /** 25 * @desc listener的回调方法名称 26 * @return 27 */ 28 String callBackMethod(); 29 }
6、代理类
1 package com.zyh.ioc.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.util.HashMap; 6 7 public class ListenerInvocationHandler implements InvocationHandler { 8 private Object target; 9 10 private HashMap<String, Method> methodMap = new HashMap<String, Method>(); 11 12 public ListenerInvocationHandler(Object target) { 13 this.target = target; 14 } 15 @Override 16 public Object invoke(Object proxy, Method method, Object[] args) 17 throws Throwable { 18 if(target != null){ 19 //执行的方法名称onClick 20 String methodName = method.getName(); 21 //toast方法 22 Method method2 = methodMap.get(methodName); 23 if(method2 != null){ 24 method2.invoke(target, args); 25 } 26 } 27 return null; 28 } 29 public Object getTarget() { 30 return target; 31 } 32 public void setTarget(Object target) { 33 this.target = target; 34 } 35 36 /** 37 * @desc 绑定方法 38 * @param name 39 * @param method 40 */ 41 public void addMethod(String name, Method method){ 42 methodMap.put(name, method); 43 } 44 }
标签:
原文地址:http://www.cnblogs.com/zhongyinghe/p/5469825.html