org.xutils.view.ViewInjectorImpl
package org.xutils.view;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.xutils.ViewInjector;
import org.xutils.common.util.LogUtil;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import org.xutils.x;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
/**
* @author 注释者:王教成
* @version 注释版:1.0.0
* 视图注入接口实现
*/
public final class ViewInjectorImpl implements ViewInjector {
private static final HashSet<Class<?>> IGNORED = new HashSet<Class<?>>();//创建忽略类集合
static {
IGNORED.add(Object.class);
IGNORED.add(Activity.class);
IGNORED.add(android.app.Fragment.class);
try {
IGNORED.add(Class.forName("android.support.v4.app.Fragment"));
IGNORED.add(Class.forName("android.support.v4.app.FragmentActivity"));
} catch (Throwable ignored) {
}
}//静态初始化块
private static final Object lock = new Object();//创建锁对象
private static volatile ViewInjectorImpl instance;//创建视图注入实例,volatile禁止优化关键字
private ViewInjectorImpl() {
}//构造器
/**
* 注册实例方法
*/
public static void registerInstance() {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new ViewInjectorImpl();
}
}
}
x.Ext.setViewInjector(instance);
}
/**
* 从父类获取注解View
* @param thisCls 此类
* @return 返回contentView注解
*/
private static ContentView findContentView(Class<?> thisCls) {
if (thisCls == null || IGNORED.contains(thisCls)) {
return null;//此类为null或者类集合包含此类返回null
}
ContentView contentView = thisCls.getAnnotation(ContentView.class);//通过此类获取注解
if (contentView == null) {
return findContentView(thisCls.getSuperclass());//注解为null则根据此类的父类返回注解
}
return contentView;//返回注解
}
/**
* 注入对象方法
* @param handler handler对象
* @param handlerType handler类型类
* @param finder ViewFinder对象
*/
@SuppressWarnings("ConstantConditions")//忽略ConstantConditions编译警告
private static void injectObject(Object handler, Class<?> handlerType, ViewFinder finder) {
if (handlerType == null || IGNORED.contains(handlerType)) {
return;//类为null或者类集合不包含,直接返回
}
injectObject(handler, handlerType.getSuperclass(), finder);//从父类到子类递归
Field[] fields = handlerType.getDeclaredFields();//获取类所有属性创建数组
if (fields != null && fields.length > 0) {
for (Field field : fields) {
Class<?> fieldType = field.getType();//属性数组非空大于0,迭代获取属性类型
if (Modifier.isStatic(field.getModifiers()) ||//不注入静态字段,getModifiers返回修饰符,Modifier判断获取修饰符
Modifier.isFinal(field.getModifiers()) ||//不注入final字段,getModifiers返回修饰符,Modifier判断获取修饰符
fieldType.isPrimitive() ||//不注入基本类型字段
fieldType.isArray()//不注入数组类型字段
) {
continue;
}
ViewInject viewInject = field.getAnnotation(ViewInject.class);//根据属性获取视图注入注解
if (viewInject != null) {
try {
View view = finder.findViewById(viewInject.value(), viewInject.parentId());//视图注解非空获取view
if (view != null) {
field.setAccessible(true);//如果view非空,将private修饰变得可访问
field.set(handler, view);//给handler对象的field字段设置成view
} else {
throw new RuntimeException("Invalid @ViewInject for "
+ handlerType.getSimpleName() + "." + field.getName());//抛出运行时异常
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);//捕获异常记录日志
}
}
}
}//注入view代码块
Method[] methods = handlerType.getDeclaredMethods();//获取类所有方法创建数组
if (methods != null && methods.length > 0) {
for (Method method : methods) {
if (Modifier.isStatic(method.getModifiers())
|| !Modifier.isPrivate(method.getModifiers())) {
continue;//不注入静态和final字段
}
//检查当前方法是否是event注解的方法
Event event = method.getAnnotation(Event.class);//根据方法获取事件注入注解
if (event != null) {
try {
int[] values = event.value();//根据事件获取ID数组
int[] parentIds = event.parentId();//根据事件获取父类ID数组
int parentIdsLen = parentIds == null ? 0 : parentIds.length;//父类ID数组为空赋长度为0,否则赋长度为数组长度
//循环所有id,生成ViewInfo并添加代理反射
for (int i = 0; i < values.length; i++) {
int value = http://www.gunmi.cn/v/values[i];//迭代ID
if (value > 0) {
ViewInfo info = new ViewInfo();//如果ID大于0创建ViewInfo对象
info.value = http://www.gunmi.cn/v/value;//赋值ID
info.parentId = parentIdsLen > i ? parentIds[i] : 0;//父类ID数组长度大于ID数组长度,返回父类ID数组i索引ID,否则返回0
method.setAccessible(true);//将private修饰变得可访问
EventListenerManager.addEventMethod(finder, info, event, handler, method);//添加事件方法
}
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);//捕获异常记录日志
}
}
}
}//注入事件代码块
}
/**
* 注入view
* @param view 视图
*/
@Override
public void inject(View view) {
injectObject(view, view.getClass(), new ViewFinder(view));//调用本类注入对象方法注入view
}
/**
* 注入activity
* @param activity 活动
*/
@Override
public void inject(Activity activity) {
Class<?> handlerType = activity.getClass();//获取Activity的类
try {
ContentView contentView = findContentView(handlerType);//调用本类方法,根据Activity的类获取ContentView注解
if (contentView != null) {
int viewId = contentView.value();//获取ContentView注解的value
if (viewId > 0) {
Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);//ID大于0,通过Activity类获取方法
setContentViewMethod.invoke(activity, viewId);//执行方法
}
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);//记录日志
}
injectObject(activity, handlerType, new ViewFinder(activity));//调用本类注入对象方法注入activity
}
/**
* 注入view holder
* @param handler view holder
* @param view 视图
*/
@Override
public void inject(Object handler, View view) {
injectObject(handler, handler.getClass(), new ViewFinder(view));//调用本类注入对象方法注入view holder
}
/**
* 注入fragment
* @param fragment 片段
* @param inflater 布局加载器
* @param container 容器
* @return 返回view
*/
@Override
public View inject(Object fragment, LayoutInflater inflater, ViewGroup container) {
//注入ContentView
View view = null;
Class<?> handlerType = fragment.getClass();//fragment对象获取类
try {
ContentView contentView = findContentView(handlerType);//根据fragment类获取注解
if (contentView != null) {
int viewId = contentView.value();//通过注解获取ID
if (viewId > 0) {
view = inflater.inflate(viewId, container, false);//如果ID大于0加载view
}
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);//记录日志
}
//注入资源和事件
injectObject(fragment, handlerType, new ViewFinder(view));//调用本类注入对象方法注入fragment
return view;//返回view
}
}