由于项目需要,开始研究ThinkAndroid。
个人认为该框架的注解机制十分新颖,所以先研究这个,顺便学习下 Java 的annotation。
粗略的看了看,该机制在BaseActivity中初始化。而BaseActivity是所有Activity的基类。
对BaseActivity进行了代码剖离,发现在BaseActivity中在onCreate函数里启动注解机制。
首先注入布局资源(绑定layout布局)
其次注入成员资源(绑定组件资源)
然后注入成员变量(初始化普通变量)
暂时先搞清楚第二个,怎么绑定组件资源的:
我写了个小demo,MyAnno
InjectView.java
[java]
package com.myanno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解,获取资源ID
* @使用方法
* @InjectView(id = R.id.settingIv)
* private ImageView imgSetting;
*
* @author michael.mao@sosino.com
* @date 2013-10-29
* @description @Retention: 定义注解的保留策略
* @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
* @Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
* @Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到
* @Inherited //说明子类可以继承父类中的该注解
*
* @Target(ElementType.TYPE) //接口、类、枚举、注解
* @Target(ElementType.FIELD) //字段、枚举的常量
* @Target(ElementType.METHOD) //方法
* @Target(ElementType.PARAMETER) //方法参数
* @Target(ElementType.CONSTRUCTOR) //构造函数
* @Target(ElementType.LOCAL_VARIABLE) //局部变量
* @Target(ElementType.ANNOTATION_TYPE)//注解
* @Target(ElementType.PACKAGE) //包
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @inte易做图ce InjectView
{
/** View的ID */
public int id() default -1;
}
MainActivity.java
[java]
package com.myanno;
import java.lang.reflect.Field;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
/** 注解绑定UI元素 */
@InjectView(id=R.id.myimgview)
ImageView myimageview;
@InjectView(id=R.id.mytext)
TextView mytext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化注解绑定的成员变量
injectView(this);
//直接使用UI元素
mytext.setText("Text0");
myimageview.setImageResource(R.drawable.junny);
}
/** 实例化@InjectView 注解的成员*/
public void injectView(Activity activity)
{
Field[] fields = activity.getClass().getDeclaredFields(); //得到Activity中的所有定义的字段
if (fields != null && fields.length > 0)
{
for (Field field : fields)
{
if (field.isAnnotationPresent(InjectView.class)) //方法返回true,如果指定类型的注解存在于此元素上
{
Log.i("Field", field.toString());
InjectView mInjectView = field.getAnnotation(InjectView.class); //获得该成员的annotation
int viewId = mInjectView.id(); //获得该注解的id
View view=activity.findViewById(viewId); //获得ID为viewID的组件对象
Log.i("Field", String.valueOf(viewId));
Log.i("Field", view.getClass().toString());
try