Android annotation

Android annotation,第1张

概述注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。在运行时读取需要使用Java反射机制进行处理。一、注解的作用:注解将一些本来重复性的工作,变成程序自动完成,简化和自动化该过程。比如用于生成Javadoc,比如编译时进行格式检查,比如自动生成代码

注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。

在运行时读取需要使用Java反射机制进行处理。

一、注解的作用:

注解将一些本来重复性的工作,变成程序自动完成,简化和自动化该过程。比如用于生成Java doc,比如编译时进行格式检查,比如自动生成代码等,用于提升软件的质量和提高软件的生产效率。

二、注解都有哪些

1、Java提供了四种元注解,专门负责新注解的创建工作,即注解其他注解。

@Target
定义了Annotation所修饰的对象范围,取值: 

ElementType.CONSTRUCTOR:用于描述构造器

ElementType.FIELD:用于描述域

ElementType.LOCAL_VARIABLE:用于描述局部变量

ElementType.METHOD:用于描述方法

ElementType.PACKAGE:用于描述包

ElementType.ParaMETER:用于描述参数

ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention
定义了该Annotation被保留的时间长短,取值:

 - RetentionPoicy.soURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;用于做一些检查性的 *** 作,比如 @OverrIDe 和 @SuppressWarnings
 - RetentionPoicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;用于在编译时进行一些预处理 *** 作,比如生成一些辅助代码(如 ButterKnife)
 - RetentionPoicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;用于在运行时去动态获取注解信息。
 

@documented
标记注解,用于描述其它类型的注解应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化,不用赋值。

@inherited
标记注解,允许子类继承父类的注解。 这里一开始有点理解不了,需要断句一下,允许子类继承父类的注解。

2、AndroID SDK内置的注解

AndroID SDK 内置的注解都在包com.androID.support:support-annotations里,下面以'com.androID.support:support-annotations:25.2.0'为例

资源引用限制类:用于限制参数必须为对应的资源类型
@AnimRes @AnyRes @ArrayRes @AttrRes @BoolRes @colorRes等

线程执行限制类:用于限制方法或者类必须在指定的线程执行
@AnyThread @BinderThread @MainThread @UiThread @WorkerThread

参数为空性限制类:用于限制参数是否可以为空
@NonNull @Nullable

类型范围限制类:用于限制标注值的值范围
@floatRang @IntRange

类型定义类:用于限制定义的注解的取值集合
@IntDef @StringDef

其他的功能性注解:
@CallSuper @CheckResult @colorInt @Dimension @Keep @Px @RequiresAPI @RequiresPermission @RestrictTo @Size @VisibleForTesting

3、自定义注解。。。。

三、如何使用AndroID Annotation

build.gradle

dependencIEs {
  androIDTestCompile('com.androID.support:support-annotations:26.1.0') {
    force = true
  }
}

举例子:

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface BtnOnClick {    int[] value();}

  

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface LayoutInject {    int value() default -1;}

  

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface OnClick {    int value();}

  

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface VIEwByID {    int value();}

  

public class AnnotationParse {    private static AnnotationParse instance;    public static AnnotationParse getInstance() {        if (instance == null) {            synchronized (AnnotationParse.class) {                if (instance == null) {                    instance = new AnnotationParse();                    return instance;                }            }        }        return instance;    }    public voID bind(Activity activity) throws illegalaccessexception {        try {            injectLayout(activity);            bindVIEw(activity);            bindOnClick(activity);            injectEvent(activity);        } catch (Exception ex) {        }    }    private static voID bindVIEw(Activity activity) throws illegalaccessexception {        //1、获取字节码        Class<? extends Activity> aClass = activity.getClass();        //2、获取Activity中变量        FIEld[] declaredFIEld = aClass.getDeclaredFIElds();        for (FIEld fIEld : declaredFIEld) {            //设置允许暴力反射            fIEld.setAccessible(true);            //3、获取变量上的注释            VIEwByID annotation = fIEld.getAnnotation(VIEwByID.class);            if (annotation != null) {                //4、获取注释上的值                int ID = annotation.value();                //5、通过ID获取控件                VIEw vIEw = activity.findVIEwByID(ID);                //6、控件赋值给变量                fIEld.set(activity, vIEw);            }        }    }    //对OnClick注解的“解释”    private static voID bindOnClick(final Activity activity) {        //1、获取字节码对象        final Class<? extends Activity> aClass = activity.getClass();        //2、获取所有的方法        Method[] declaredMethods = aClass.getDeclaredMethods();        //3、遍历所有的方法        for (final Method method : declaredMethods) {            method.setAccessible(true);            //4、获取方法上的注释            OnClick annotation = method.getAnnotation(OnClick.class);            if (annotation != null) {                int ID = annotation.value();                VIEw vIEw = activity.findVIEwByID(ID);                vIEw.setonClickListener(new VIEw.OnClickListener() {                    @OverrIDe                    public voID onClick(VIEw v) {                        try {                            //执行注解的方法                            method.invoke(activity, null);                        } catch (illegalaccessexception e) {                            e.printstacktrace();                        } catch (InvocationTargetException e) {                            e.printstacktrace();                        }                    }                });            }        }    }    private static voID injectEvent(final Activity activity) {        Class<? extends Activity> clazz = activity.getClass();        Method[] methods = clazz.getDeclaredMethods();        for (final Method method2 : methods) {            BtnOnClick click = method2.getAnnotation(BtnOnClick.class);            if (click != null) {                int[] vIEwID = click.value();                method2.setAccessible(true);                Object Listener = Proxy.newProxyInstance(VIEw.OnClickListener.class.getClassLoader(),                        new Class[]{VIEw.OnClickListener.class}, new InvocationHandler() {                            @OverrIDe                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                                return method2.invoke(activity, args);                            }                        });                try {                    for (int ID : vIEwID) {                        VIEw v = activity.findVIEwByID(ID);                        Method setClickListener = v.getClass().getmethod("setonClickListener", VIEw.OnClickListener.class);                        setClickListener.invoke(v, Listener);                    }                } catch (Exception e) {                    e.printstacktrace();                }            }        }    }    private static int mLayoutID = -1;    /**     * 注解布局Layout ID     */    private static voID injectLayout(Activity activity) {        Class<?> clazz = activity.getClass();        if (clazz.getAnnotations() != null) {            if (clazz.isAnnotationPresent(LayoutInject.class)) {                LayoutInject inject = clazz.getAnnotation(LayoutInject.class);                mLayoutID = inject.value();                activity.setContentVIEw(mLayoutID);            }        }    }}

  

@LayoutInject(R.layout.activity_main)public class MainActivity extends AppCompatActivity {    @VIEwByID(R.ID.tvname)    TextVIEw tvname;    @VIEwByID(R.ID.tvAge)    TextVIEw tvAge;    @VIEwByID(R.ID.tvGender)    TextVIEw tvGender;    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //setContentVIEw(R.layout.activity_main);        try {            AnnotationParse.getInstance().bind(this);        } catch (illegalaccessexception e) {            e.printstacktrace();        }        tvname.setText("测试名字");        tvAge.setText("28");        tvGender.setText("男");    }    @BtnOnClick({R.ID.tvname, R.ID.tvAge, R.ID.tvGender})    public voID btnOnClick(VIEw vIEw) {        switch (vIEw.getID()) {            case R.ID.tvname:                tvname.setText("华山论剑");                break;            case R.ID.tvAge:                tvAge.setText("四百多岁");                break;            case R.ID.tvGender:                tvGender.setText("女");                break;        }    }    @OnClick(R.ID.tvname)    public voID textOnClick() {        tvname.setText("华山论剑");    }}

  

总结

以上是内存溢出为你收集整理的Android annotation全部内容,希望文章能够帮你解决Android annotation所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1067289.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存