Android实现注解的方式

关于注解,之前一直也没有接触过,最一开始使用是在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("注解是否成功!");
    }
}


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



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值