github官网:
https://github.com/wyouflf/xUtils3
简单使用
public class MainActivity extends AppCompatActivity {
@ViewInject(R.id.test_tv)
TextView mTextTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
x.view().inject(this);
mTextTv.setText("xutils的使用");
}
@Event(value = R.id.test_iv,
type = View.OnClickListener.class/*可选参数, 默认是View.OnClickListener.class*/)
private void onTestBaidu1Click(View view) {
Toast.makeText(getApplicationContext(),"图片",Toast.LENGTH_SHORT).show();
}
}
源码分析
x.view().inject(this);源码分析
inject实际就是一个接口,参数有Activity或者Fragment等
x.vjew()实际返回的ViewInjectorImpl对象,看inject方法
@Override
public void inject(Activity activity) {
//获取Activity的ContentView的注解,这里是我们的MainActivity
Class> handlerType = activity.getClass();
try {
//①对其进行分析,返回ContentView
ContentView contentView = findContentView(handlerType);
if (contentView != null) {
//获取ContentView中的值
int viewId = contentView.value();
if (viewId > 0) {
//获取MainActivity中的setContentView的方法
Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
//反射执行该方法
setContentViewMethod.invoke(activity, viewId);
}
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
//传入的Activity,改activity中所有的注解,ViewFinder对象
injectObject(activity, handlerType, new ViewFinder(activity));
}
①findContentView源码分析
/**
* 从父类获取注解View
*/
private static ContentView findContentView(Class> thisCls) {
if (thisCls == null || IGNORED.contains(thisCls)) {
return null;
}
//MainActivity中的ContentView的注解
ContentView contentView = thisCls.getAnnotation(ContentView.class);
if (contentView == null) {
//获得本类的父类
return findContentView(thisCls.getSuperclass());
}
return contentView;
}
injectObject(activity, handlerType, new ViewFinder(activity));源码分析
private static void injectObject(Object handler, Class> handlerType, ViewFinder finder) {
if (handlerType == null || IGNORED.contains(handlerType)) {
return;
}
// 从父类到子类递归
injectObject(handler, handlerType.getSuperclass(), finder);
// inject view获得所有的属性
Field[] fields = handlerType.getDeclaredFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
//所有属性的类型
Class> fieldType = field.getType();
if (
/* 不注入静态字段 */ Modifier.isStatic(field.getModifiers()) ||
/* 不注入final字段 */ Modifier.isFinal(field.getModifiers()) ||
/* 不注入基本类型字段 */ fieldType.isPrimitive() ||
/* 不注入数组类型字段 */ fieldType.isArray()) {
continue;
}
//获得所有注解ViewInject,如TextView
ViewInject viewInject = field.getAnnotation(ViewInject.class);
if (viewInject != null) {
try {
View view = finder.findViewById(viewInject.value(), viewInject.parentId());
if (view != null) {
//所有设置属性都可以
field.setAccessible(true);
field.set(handler, view);
} else {
throw new RuntimeException("Invalid @ViewInject for "
+ handlerType.getSimpleName() + "." + field.getName());
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
} // end inject 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;
}
//检查当前方法是否是event注解的方法
Event event = method.getAnnotation(Event.class);
if (event != null) {
try {
// id参数
int[] values = event.value();
int[] parentIds = event.parentId();
int parentIdsLen = parentIds == null ? 0 : parentIds.length;
//循环所有id,生成ViewInfo并添加代理反射
for (int i = 0; i < values.length; i++) {
int value = values[i];
if (value > 0) {
ViewInfo info = new ViewInfo();
info.value = value;
info.parentId = parentIdsLen > i ? parentIds[i] : 0;
method.setAccessible(true);
//源码分析
EventListenerManager.addEventMethod(finder, info, event, handler, method);
}
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
} // end inject event
}
public static void addEventMethod(
//根据页面或view holder生成的ViewFinder
ViewFinder finder,
//根据当前注解ID生成的ViewInfo
ViewInfo info,
//注解对象
Event event,
//页面或view holder对象
Object handler,
//当前注解方法
Method method) {
try {
View view = finder.findViewByInfo(info);
if (view != null) {
// 注解中定义的接口,比如Event注解默认的接口为View.OnClickListener
Class> listenerType = event.type();
// 默认为空,注解接口对应的Set方法,比如setOnClickListener方法
String listenerSetter = event.setter();
if (TextUtils.isEmpty(listenerSetter)) {
listenerSetter = "set" + listenerType.getSimpleName();
}
String methodName = event.method();
boolean addNewMethod = false;
/*
根据View的ID和当前的接口类型获取已经缓存的接口实例对象,
比如根据View.id和View.OnClickListener.class两个键获取这个View的OnClickListener对象
*/
Object listener = listenerCache.get(info, listenerType);
DynamicHandler dynamicHandler = null;
/*
如果接口实例对象不为空
获取接口对象对应的动态代理对象
如果动态代理对象的handler和当前handler相同
则为动态代理对象添加代理方法
*/
if (listener != null) {
dynamicHandler = (DynamicHandler) Proxy.getInvocationHandler(listener);
addNewMethod = handler.equals(dynamicHandler.getHandler());
if (addNewMethod) {
dynamicHandler.addMethod(methodName, method);
}
}
// 如果还没有注册此代理
if (!addNewMethod) {
dynamicHandler = new DynamicHandler(handler);
dynamicHandler.addMethod(methodName, method);
// 生成的代理对象实例,比如View.OnClickListener的实例对象
listener = Proxy.newProxyInstance(
listenerType.getClassLoader(),
new Class>[]{listenerType},
dynamicHandler);
listenerCache.put(info, listenerType, listener);
}
Method setEventListenerMethod = view.getClass().getMethod(listenerSetter, listenerType);
setEventListenerMethod.invoke(view, listener);
}
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}