Android实现注解的方式

来源:互联网 发布:淘宝怎么实名认证手机 编辑:程序博客网 时间:2024/05/16 17:56

关于注解,之前一直也没有接触过,最一开始使用是在xUtils框架的ViewUtils模块的功能。感觉用起来甚是方便,但是很多时候还是想要用自己的编写的工具类,也算是学习吧,毕竟人家的框架是为了提高开发效率,但是自己也不能只会用而不会写,所以特在网上找了些大牛写的文章,总结了一下,找了两种比较不错的实现方式,现在贴上以后再慢慢理解。也欢迎大家给出指导意见。

首先是第一种方式,分别定义了两种注解:一个是针对控件的,另一个是针对layout布局的。

首先贴代码,使用方法后边会写到:

第一个注解类,针对layout使用的:

GetLayout.java

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by Administrator on 2016/3/24. */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface GetLayout {    int value();}

第二个注解类,针对控件使用的:

GetView.java

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by Administrator on 2016/3/24. *//*  因为这个注释我们要运在类的成员变量上,所以我们要申明@ElementType.FILELD。类成员变量指定我们申明的控件对象 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface GetView {    int value();}


最后一个类:

UtilsReten.java  注解具体实现的类


import android.app.Activity;import android.view.View;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * Created by Administrator on 2016/3/24. */public class UtilsReten {    public static void injectObject(Object object, Activity activity) {        Class<?> classType = object.getClass();        // 该类是否存在GetLayout类型的注解        if (classType.isAnnotationPresent(GetLayout.class)) {            // 返回存在的GetLayout类型的注解            GetLayout annotation = classType.getAnnotation(GetLayout.class);            try {                Method method = classType.getMethod("setGetLayout", int.class); //这里还是不太明白是怎么得到这个方法的,还望大神解答                int resId = annotation.value();                method.invoke(object, resId);            } catch (Exception e) {                e.printStackTrace();            }        }        // 返回 Field 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的成员变量,        // 包括公共、保护、默认(包)访问和私有成员变量,但不包括继承的成员变量。        Field[] fields = classType.getDeclaredFields();        if (null != fields && fields.length > 0) {            for (Field field : fields) {//                改成员变量是否存在GetView类型的注解                if (field.isAnnotationPresent(GetView.class)) {                    GetView annotation = field.getAnnotation(GetView.class);                    int viewId = annotation.value();                    View view = activity.findViewById(viewId);                    if (null != view) {                        try {                            field.setAccessible(true);                            field.set(object, view);                        } catch (IllegalAccessException e) {                            e.printStackTrace();                        }                    }                }            }        }    }}

接下来在一个测试的Activity中使用就可以了

MainActivity.java

import android.os.Bundle;import android.support.annotation.Nullable;import android.widget.TextView;@GetLayout(R.layout.content_main)public class MainActivity extends Activity {    @GetView(R.id.hello_world)    TextView tx;        @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        UtilsReten.injectObject(this,this);        tx.setText("注解是否成功!");    }}

接下来是第二种方式:

ViewInject.java  做注解接口:

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by Administrator on 2016/3/24. */@Target(ElementType.FIELD) //表示运用在字段上@Retention(RetentionPolicy.RUNTIME) public @interface ViewInject {    int value() default 0;}

接下来是使用的类:

UtilsInject.java

import android.app.Activity;import android.support.v4.app.FragmentActivity;import java.lang.reflect.Field;/** * Created by Administrator on 2016/3/24. */public class UtilsInject {    public static void injectField(Activity activity) {        try {            Class<?> clazz = activity.getClass();            Field[] fields = clazz.getDeclaredFields();            for (Field field : fields) {                if (field.isAnnotationPresent(ViewInject.class)) {                    ViewInject inject = field.getAnnotation(ViewInject.class);                    int id = inject.value();                    if (id > 0) {                        field.setAccessible(true);                        field.set(activity, activity.findViewById(id));                    }                }            }        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }}
用法很简单:

MainActivity.java

import android.app.Activity;import android.os.Bundle;import android.support.annotation.Nullable;import android.widget.TextView;public class MainActivity extends Activity {    @ViewInject(R.id.hello_world)    TextView tx;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.content_main);        UtilsInject.injectField(this);        tx.setText("注解是否成功!");    }}


以上就是两种实现注解的方式,因为也是在网上多方找资料看的,有些地方可能理解不是很透彻,还带深入理解,如果有大神看到的略有指点下就更好了



0 0
原创粉丝点击