码迷,mamicode.com
首页 > 其他好文 > 详细

ioc构架demo

时间:2016-05-08 10:20:45      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:

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 }

 

ioc构架demo

标签:

原文地址:http://www.cnblogs.com/zhongyinghe/p/5469825.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!