android 进阶之注解框架搭建

Posted silly_wy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 进阶之注解框架搭建相关的知识,希望对你有一定的参考价值。


今天重点内容是android懒人式开发(注解)框架的搭建。废话不多说,请看图:

@contentView这个注解呢就是延伸在类之上的,只有类才能使用这个标签,表示引用那个activity的xml。
@findViewById这个注解呢是用在类里面的字段上,表示通过这个id找到这个控件并赋值给用于这个标签的控件上。


下面来看代码:首先我们先看2个注解类,contentView这个注解类主要是作用于类,而findViewById这个注解类主要是作用于字段。并且这2个类都可以通过JVM或其他使用反射机制的代码所读取和使用。

package com.wyw.annotationdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//ElementType.TYPE表示着这个注解作用于类、接口或枚举;
//ElementType.FIELD表示着这个注解作用于字段;
//ElementType.METHOD表示着这个注解作用于方法;
//ElementType.PARAMETER表示着这个注解作用于参数;
//ElementType.CONSTRUCTOR表示着这个注解作用于构造函数;
//ElementType.LOCAL_VARIABLE表示着这个注解作用于局部变量;
//ElementType.ANNOTATION_TYPE表示着这个注解作用于注释类型;
//ElementType.PACKAGE  表示着这个注解作用于包;

//RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略
//RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
//RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface contentView 
    int value();//布局id

-------------------------------------------

package com.wyw.annotationdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface findViewById 
    int value();//控件id

注解类已经写完,现在该是看调用注解的并反射activity方法的类了:

initContentView这个方法呢是初始化activity的xml。通过class拿到类的注解,并且直接反射该类的setContentView,并把注解的id传进去。

initView这个方法是把控件findViewById出来,首先我们先拿到类里面的所有属性(字段),并且通过这个属性拿到这个属性的注解,通过反射该类的findViewById方法,并且把注解的id传进去。通过反射拿到id的控件,并且把这个控件设置给这个属性(字段)。

package com.wyw.annotationdemo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.app.Activity;

public class AnnotateUtils 
    /** 通过类注解来设置布局 */
    public static void initContentView(Activity activity) 
        Class<? extends Activity> clazz = activity.getClass();
        // 拿到类的注解(因为是类注解所以要直接用类来拿)
        contentView cView = clazz.getAnnotation(contentView.class);
        if (cView != null) 
            try 
                // 拿到指定方法
                Method method = clazz.getMethod("setContentView", int.class);
                // 拿到findViewById这个方法返回回来的view
                method.invoke(activity, cView.value());
             catch (Exception e) 
                e.printStackTrace();
             
        
    

    /** 通过注解设置控件值 */
    public static void initView(Activity activity) 
        Class<? extends Activity> clazz = activity.getClass();
        // 获得类的所有属性。
        Field[] fields = clazz.getDeclaredFields();
        // 遍历所有成员变量
        for (Field field : fields) 
            // 拿到属性注解(因为是类里面的属性注解,所以要再类里面的属性里面拿)
            findViewById viewById = field.getAnnotation(findViewById.class);
            if (viewById != null) 
                int viewId = viewById.value();
                if (viewId != -1) 
                    try 
                        // 初始化View
                        Method method = clazz.getMethod("findViewById",int.class);
                        // 拿到findViewById这个方法返回回来的view
                        Object resView = method.invoke(activity, viewId);
                        field.setAccessible(true);
                        // 设置注解下面的属性的值 = resView;
                        field.set(activity, resView);
                     catch (Exception e) 
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    
                
            
        
    

注解和反射都写完了,接下来该写个基类来调用这个反射了,代码如下:AnnotateUtils.initContentView(this);调用activity的xml。AnnotateUtils.initView(this);初始化控件

package com.wyw.annotationdemo;

import android.app.Activity;
import android.os.Bundle;

public abstract class BaseActivity extends Activity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        AnnotateUtils.initContentView(this);
        AnnotateUtils.initView(this);
        init();
    

    /** 初始化 */
    protected abstract void init();



本篇博客就到这里,如果有有疑问的欢迎留言讨论。同时希望大家多多关注我的博客,多多支持我。

尊重原创转载请注明:(http://blog.csdn.net/u013895206) !

下面是地址传送门:址:http://download.csdn.net/detail/u013895206/9482743

以上是关于android 进阶之注解框架搭建的主要内容,如果未能解决你的问题,请参考以下文章

Android搭建应用框架系列之BaseActivity

Android进阶之注解解析和自定义注解

Android进阶必学:自定义注解之反射

Android进阶必学:自定义注解之动态代理

Android进阶之光学习记录——注解与依赖注入框架ButterKnife的尝试

Android进阶之光学习记录——注解与依赖注入框架ButterKnife的尝试