要实现的目标结果如下 :
@ContentView(R.layout.activity_main) public class MainActivity extends Activity implements View.OnClickListener { @ViewInject(R.id.id_btn) private Button mBtn1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewUtil.inject(this);
1、定义注解
首先我们需要两个注解文件:1.1
package com.zhy.ioc.view.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView
{
int value();
}
ContentView用于在类上使用,主要用于标明该Activity需要使用的布局文件
@ContentView(value = R.layout.activity_main)
public class MainActivity
1.2
package com.zhy.ioc.view.annotation;
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 ViewInject
{
int value();
}
在成员变量上使用,用于指定View的Id
@ViewInject(R.id.id_btn)
private Button mBtn1;
此两个注解定义,需分别写在两个类文件上
ContentView.java
ViewInject.java
2、MainActivity
package com.example.administrator.camera;
import android.app.Activity;
import android.jni.ContentView;
import android.jni.ViewInject;
import android.jni.ViewUtil;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
@ContentView(R.layout.activity_main)
public class MainActivity extends Activity implements View.OnClickListener {
@ViewInject(R.id.id_btn)
private Button mBtn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewUtil.inject(this);
// mBtn1.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// Toast.makeText(MainActivity.this, "how old are you ?", Toast.LENGTH_SHORT).show();
// }
// });
mBtn1.setOnClickListener(this);
}
public void onClick(View v)
{
switch (v.getId())
{
case R.id.id_btn:
Toast.makeText(MainActivity.this, "Why do you click me ?",
Toast.LENGTH_SHORT).show();
break;
}
}
}
注解都写好了,核心的代码就是
ViewUtil.inject(this);
ViewUtil.inject(this);
ViewUtil.java
如下:
package android.jni;
import android.app.Activity;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by Administrator on 2017-11-20.
*/
/**
* 核心控制类
*
* @author leilu
*
*/
public class ViewUtil {
public static void inject(Activity activity)
{
injectContentView(activity);
injectViews(activity);
}
private static final String METHOD_SET_CONTENTVIEW = "setContentView";
/**
* 注入主布局文件
*
* @param activity
*/
private static void injectContentView(Activity activity)
{
Class<? extends Activity> clazz = activity.getClass();
// 查询类上是否存在ContentView注解
ContentView contentView = clazz.getAnnotation(ContentView.class);
if (contentView != null)// 存在
{
int contentViewLayoutId = contentView.value();
try
{
Method method = clazz.getMethod(METHOD_SET_CONTENTVIEW,
int.class);
method.setAccessible(true);
method.invoke(activity, contentViewLayoutId);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
private static final String METHOD_FIND_VIEW_BY_ID = "findViewById";
/**
* 注入所有的控件
*
* @param activity
*/
private static void injectViews(Activity activity)
{
Class<? extends Activity> clazz = activity.getClass();
Field[] fields = clazz.getDeclaredFields();
// 遍历所有成员变量
for (Field field : fields)
{
ViewInject viewInjectAnnotation = field
.getAnnotation(ViewInject.class);
if (viewInjectAnnotation != null)
{
int viewId = viewInjectAnnotation.value();
if (viewId != -1)
{
Log.e("TAG", viewId+"");
// 初始化View
try
{
Method method = clazz.getMethod(METHOD_FIND_VIEW_BY_ID,
int.class);
Object resView = method.invoke(activity, viewId);
field.setAccessible(true);
field.set(activity, resView);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
参考文献:http://android.jobbole.com/81051/
http://android.jobbole.com/81053/