**由于分离开讲解代码片段,读者看起来缺乏整体感,不容易记忆,
先提出要说的整段代码,方便查看。**
讲解会直接添加到代码的中,有需要重点说明的会在文章结尾详细说明。
public class ViewUtils {
//无参构造
private ViewUtils() {
}
//view注入的方法重载
public static void inject(View view) {
injectObject(view, new ViewFinder(view));
}
// Activity注入的方法重载
public static void inject(Activity activity) {
injectObject(activity, new ViewFinder(activity));
}
// PreferenceActivity 注入的方法重载
public static void inject(PreferenceActivity preferenceActivity) {
injectObject(preferenceActivity, new ViewFinder(preferenceActivity));
}
// handler,view注入的方法重载
public static void inject(Object handler, View view) {
injectObject(handler, new ViewFinder(view));
}
// handler,Activity 注入的方法重载
public static void inject(Object handler, Activity activity) {
injectObject(handler, new ViewFinder(activity));
}
// handler,PreferenceGroup 注入的方法重载
public static void inject(Object handler, PreferenceGroup preferenceGroup) {
injectObject(handler, new ViewFinder(preferenceGroup));
}
// handler,PreferenceActivity 注入的方法重载
public static void inject(Object handler, PreferenceActivity preferenceActivity) {
injectObject(handler, new ViewFinder(preferenceActivity));
}
//核心的方法
@SuppressWarnings("ConstantConditions")
private static void injectObject(Object handler, ViewFinder finder) {
//使用到反射机制
Class<?> handlerType = handler.getClass();
// inject ContentView 注入ContentView
ContentView contentView = handlerType.getAnnotation(ContentView.class);
if (contentView != null) {
try {
Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
setContentViewMethod.invoke(handler, contentView.value());
} catch (Throwable e) {
LogUtils.e(e.getMessage(), e);
}
}
// inject view注入view
Field[] fields = handlerType.getDeclaredFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
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);
}
} catch (Throwable e) {
LogUtils.e(e.getMessage(), e);
}
} else {
ResInject resInject = field.getAnnotation(ResInject.class);
if (resInject != null) {
try {
Object res = ResLoader.loadRes(
resInject.type(), finder.getContext(), resInject.id());
if (res != null) {
field.setAccessible(true);
field.set(handler, res);
}
} catch (Throwable e) {
LogUtils.e(e.getMessage(), e);
}
} else {
PreferenceInject preferenceInject = field.getAnnotation(PreferenceInject.class);
if (preferenceInject != null) {
try {
Preference preference = finder.findPreference(preferenceInject.value());
if (preference != null) {
field.setAccessible(true);
field.set(handler, preference);
}
} catch (Throwable e) {
LogUtils.e(e.getMessage(), e);
}
}
}
}
}
}
// inject event注入事件
Method[] methods = handlerType.getDeclaredMethods();
if (methods != null && methods.length > 0) {
for (Method method : methods) {
Annotation[] annotations = method.getDeclaredAnnotations();
if (annotations != null && annotations.length > 0) {
for (Annotation annotation : annotations) {
Class<?> annType = annotation.annotationType();
if (annType.getAnnotation(EventBase.class) != null) {
method.setAccessible(true);
try {
// ProGuard:-keep class * extends java.lang.annotation.Annotation { *; }
Method valueMethod = annType.getDeclaredMethod("value");
Method parentIdMethod = null;
try {
parentIdMethod = annType.getDeclaredMethod("parentId");
} catch (Throwable e) {
}
Object values = valueMethod.invoke(annotation);
Object parentIds = parentIdMethod == null ? null : parentIdMethod.invoke(annotation);
int parentIdsLen = parentIds == null ? 0 : Array.getLength(parentIds);
int len = Array.getLength(values);
for (int i = 0; i < len; i++) {
ViewInjectInfo info = new ViewInjectInfo();
info.value = Array.get(values, i);
info.parentId = parentIdsLen > i ? (Integer) Array.get(parentIds, i) : 0;
EventListenerManager.addEventMethod(finder, info, annotation, handler, method);
}
} catch (Throwable e) {
LogUtils.e(e.getMessage(), e);
}
}
}
}
}
}
}