com.hadoopz.MyDroidLib.inject.ViewInjectorImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2018 jw362j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hadoopz.MyDroidLib.inject;
import java.util.HashSet;
import android.app.Activity;
import android.view.View;
import java.lang.reflect.Method;
import android.view.LayoutInflater;
import com.hadoopz.MyDroidLib.inject.annotation.ContentView;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import android.view.ViewGroup;
import com.hadoopz.MyDroidLib.inject.annotation.Event;
import com.hadoopz.MyDroidLib.inject.annotation.ViewInject;
import com.mycomm.IProtocol.log.UniversalLogHolder;
import java.lang.reflect.InvocationTargetException;
/**
*
* @author jw362j
*/
public class ViewInjectorImpl implements ViewInjector{
private static final String TAG = "ViewInjectorImpl";
private static final HashSet> IGNORED = new HashSet>();
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;
private ViewInjectorImpl() {
}
public static void registerInstance() {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new ViewInjectorImpl();
}
}
}
y.setViewInjector(instance);
}
@Override
public void inject(View view) {
injectObject(view, view.getClass(), new ViewFinder(view));
}
@Override
public void inject(Activity activity) {
//获取Activity的ContentView的注解
Class> handlerType = activity.getClass();
try {
ContentView contentView = findContentView(handlerType);
if (contentView != null) {
int viewId = contentView.value();
if (viewId > 0) {
Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
setContentViewMethod.invoke(activity, viewId);
}
}
} catch (NoSuchMethodException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
} catch (SecurityException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
} catch (IllegalAccessException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
} catch (IllegalArgumentException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
} catch (InvocationTargetException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
}
injectObject(activity, handlerType, new ViewFinder(activity));
}
@Override
public void inject(Object handler, View view) {
injectObject(handler, handler.getClass(), new ViewFinder(view));
}
@Override
public View inject(Object fragment, LayoutInflater inflater, ViewGroup container) {
// inject ContentView
View view = null;
Class> handlerType = fragment.getClass();
try {
ContentView contentView = findContentView(handlerType);
if (contentView != null) {
int viewId = contentView.value();
if (viewId > 0) {
view = inflater.inflate(viewId, container, false);
}
}
} catch (Throwable ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
}
// inject res & event
injectObject(fragment, handlerType, new ViewFinder(view));
return view;
}
/**
* 从父类获取注解View
*/
private static ContentView findContentView(Class> thisCls) {
if (thisCls == null || IGNORED.contains(thisCls)) {
return null;
}
ContentView contentView = thisCls.getAnnotation(ContentView.class);
if (contentView == null) {
return findContentView(thisCls.getSuperclass());
}
return contentView;
}
@SuppressWarnings("ConstantConditions")
private static void injectObject(Object handler, Class> handlerType, ViewFinder finder) {
y.log("in injectObject,handler:"+handler+",handlerType:"+handlerType+",finder:"+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 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 (IllegalAccessException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
} catch (RuntimeException ex) {
UniversalLogHolder.e(TAG, ex.getMessage());
}
}
}
} // end inject view
// inject event
Method[] methods = handlerType.getDeclaredMethods();
y.log("in injectObject,methods:"+methods);
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) {
y.log("in injectObject,method is Annotation by Event");
try {
// id参数
int[] values = event.value();
int[] parentIds = event.parentId();
int parentIdsLen = parentIds == null ? 0 : parentIds.length;
y.log("in injectObject,values:"+values+",method:"+method);
//循环所有id,生成ViewInfo并添加代理反射
if(values != null){
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) {
UniversalLogHolder.e(TAG,ex.getMessage());
}
}
}
} else{
y.log("in injectObject,methods is null");
}
}
}