java反射在安卓中的部分应用

 

1.反射(Reflect)API                                                 

API    描述 举例
 getClass 获取类 Class cls = this.getClass()
getAnnotation(XX.class)   获取注解 

 clazz.getAnnotation()获取类之上的注解 

                                     获取方法之上的注解 

  field.getAnnotation()获取属性之上的注解   

getMethod()获取方法 
invoke(xx, yy)执行方法 
getDeclaredMethods()获取所有方法 
getDeclaredFields()获取所有属性 
annotationType()获取注解类型

 

      解释:   getMethod()/getMethods()与 getDeclaredMethods()/getDeclaredMethods()的区别:

                     前者获取当前类以及它的父类的public方法       

                       后者只能获取当前类的所有方法 

                      获取属性同理   

应用   

给控件加注解,替换findViewById

      1.新建一个控件注解

/**
 * Created by everrise on 2019/9/3.
 */
@Target(ElementType.FIELD)       //该注解只能作用在类之上
@Retention(RetentionPolicy.RUNTIME)//SOURCE做代码检测属于源码级, jvm在运行时通过反射的技术获取
public @interface InjectView {

    //返回int类型的值
    int value();
}

ElementType.TYPE:表示作用在类之上; ElementType.METHOD: 作用在方法之上;ElementType.FIELD:作用在属性之上

ElementType.CONSTRUCTOR:作用在构造方法之上;ElementType.ANNOTATION_TYPE:作用在另一个注解之上

ElementType.PACKAGE:作用在包之上 ; ElementType.PARAMETER:作用在属性之上

ElementType.LOCAL_VARIABLE:作用在局部属性之上

2.创建一个InjectManager类,并在BaseActivity的onCreate方法中调用


public class BaseActivity extends Activity{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        InjectManager.inject(this);
    }
}

3.injectViews(activity);中通过反射注解找到需要的控件id并赋值给控件

public class InjectManager {
    
    public static void inject(Activity activity) {
        //布局的注入
        injectLayout(activity);
        //view注入
        injectViews(activity);
    }

    private static void injectViews(Activity activity) {
        //获取类
        Class<? extends Activity> clazz = activity.getClass();
        //获取所有属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field field:fields) {
            //获取属性的注解
            InjectView injectView = field.getAnnotation(InjectView.class);
            if(injectView !=null){
                //获取注解的值
                int viewId = injectView.value();
                //获取findviewbyid
                try {
                    Method method = clazz.getMethod("findViewById", int.class);
                    Object view = method.invoke(activity, viewId);

                    field.setAccessible(true);//设置私有属性可以访问
                    field.set(activity, view);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }

    }

    private static void injectLayout(Activity activity) {
        //获取类
        Class<? extends Activity> clazz = activity.getClass();
        //获取类的注解
        ContentView contentView = clazz.getAnnotation(ContentView.class);
        //获取注解的值
        int layoutId = contentView.value();//布局id
        //获取方法setContentView
        try {
            Method method = clazz.getMethod("setContentView", int.class);
            //执行方法
            method.invoke(activity,layoutId);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

4.MainActivity继承BaseActivity使用注解

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {

    @InjectView(R.id.btn)
    private Button btn;

    @InjectView(R.id.tv)
    private TextView tv;

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

5.注解替换setContentView同理

@Target(ElementType.TYPE)  //该注解只能作用在类之上
@Retention(RetentionPolicy.RUNTIME)//SOURCE做代码检测属于源码级, jvm在运行时通过反射的技术获取注解的值
public @interface ContentView {

    //返回int类型的布局值
    int value();
}

注:本文来自网易Android公开课。非原创,仅做学习记录,ths

 

                                        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值