ButterKnife,XUtils,RockaIOC !
定义
AOP
AOP(Aspect Oriented Programming 面向切面编程)技术是建立在JAVA反射和动态代理的基础上的。调用者直接调用的其实AOP容器动态生成的代理对象,再由代理对象调用目标对象完成原始的业务逻辑。
- 处理核心业务的时候难免会遇到以前相同逻辑的业务处理(Android 动态申请危险权限,Android 网络监测等)这个时候比较常用的就是AOP来进行处理了。
IOC
IOC(Inversion of Control 控制反转)即让调用类对某一接口具体实现类的选择控制权从调用类中移除交给第三方。换一种说法那就是依赖注入即调用类对某一接口实现类的依赖关系由第三方(容器)注入,以移除调用类对某一接口实现类的依赖。
- 注入方式可以分为三种:构造函数注入、属性注入和接口注入、
注解
自定义注解比较简单,简单解释下就是,注解就像是一种标记,加了注解就像是打了标记,程序可以利用JAVA 的反射机制来了解你的类及各种元素上的标记,在针对不同标记来做对应的事。
1 2 3 4 5 6 7
| @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) public @interface EventViewById { int value(); }
|
反射
主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。 反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接,反射使用不当会成本很高。
- API在:package java.lang.reflect
- 反射简单用法:
1 2 3 4 5 6 7
| Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields();
Class clazz = object.getClass(); Method[] methods = clazz.getDeclaredMethods();
|
常见IOC框架
XUtils(xutils:3.5.0)
源码解析:
1.单例模式实例化 ViewInjectorImpl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
x.view().inject(this);
public static ViewInjector view() { if (Ext.viewInjector == null) { ViewInjectorImpl.registerInstance(); } return Ext.viewInjector; }
public static void registerInstance() { if (instance == null) { synchronized (lock) { if (instance == null) { instance = new ViewInjectorImpl(); } } } x.Ext.setViewInjector(instance); }
|
2.注入Object,通过反射拿到注解,并且拿到注解的值,在设置到属性或者方法中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| @SuppressWarnings("ConstantConditions") private static void injectObject(Object handler, Class<?> handlerType, ViewFinder finder) { if (handlerType == null || IGNORED.contains(handlerType)) { return; }
injectObject(handler, handlerType.getSuperclass(), finder);
Field[] fields = handlerType.getDeclaredFields(); if (fields != null && fields.length > 0) { for (Field field : fields) {
Class<?> fieldType = field.getType(); if ( Modifier.isStatic(field.getModifiers()) || 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 (Throwable ex) { LogUtil.e(ex.getMessage(), ex); } } } }
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 = method.getAnnotation(Event.class); if (event != null) { try { int[] values = event.value(); int[] parentIds = event.parentId(); int parentIdsLen = parentIds == null ? 0 : parentIds.length; 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); } } } }
}
|
ButterKnife(butterknife:8.8.1)
ButerKnife主要会引入两个module(1个是他的核心实现,1个是他的所有的注解)
简单点就是
1.编译的时候ButterKnifeProcessor 生成 .java –> class文件
2.运行是viewBinder.bind(finder, target, source);
源码解析:
1 2 3 4 5
| @NonNull @UiThread public static Unbinder bind(@NonNull Activity target) { View sourceView = target.getWindow().getDecorView(); return createBinding(target, sourceView); }
|
在点到createBinding()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| private static Unbinder createBinding(@NonNull Object target, @NonNull View source) { Class<?> targetClass = target.getClass(); if (debug) Log.d(TAG, "Looking up binding for " + targetClass.getName()); Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass);
if (constructor == null) { return Unbinder.EMPTY; }
try { return constructor.newInstance(target, source); } catch (IllegalAccessException e) { throw new RuntimeException("Unable to invoke " + constructor, e); } catch (InstantiationException e) { throw new RuntimeException("Unable to invoke " + constructor, e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } if (cause instanceof Error) { throw (Error) cause; } throw new RuntimeException("Unable to create binding instance.", cause); } }
|
createBinding()方法主要就是拿到我们绑定的Activity的Class,然后通过Constructor构造器获取一个Unbinder子类的构造方法,然后在调用newInstance(target, source)通过构造方法获取到Unbinder子类的一个实例,这里传入两个参数,说明构造方法里需要两个参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| @Nullable @CheckResult @UiThread private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) { Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls); if (bindingCtor != null) { if (debug) Log.d(TAG, "HIT: Cached in binding map."); return bindingCtor; } String clsName = cls.getName(); if (clsName.startsWith("android.") || clsName.startsWith("java.")) { if (debug) Log.d(TAG, "MISS: Reached framework class. Abandoning search."); return null; } try { Class<?> bindingClass = cls.getClassLoader().loadClass(clsName + "_ViewBinding"); bindingCtor = (Constructor<? extends Unbinder>) bindingClass.getConstructor(cls, View.class); if (debug) Log.d(TAG, "HIT: Loaded binding class and constructor."); } catch (ClassNotFoundException e) { if (debug) Log.d(TAG, "Not found. Trying superclass " + cls.getSuperclass().getName()); bindingCtor = findBindingConstructorForClass(cls.getSuperclass()); } catch (NoSuchMethodException e) { throw new RuntimeException("Unable to find binding constructor for " + clsName, e); } BINDINGS.put(cls, bindingCtor); return bindingCtor; }
|
1 2 3 4
|
@VisibleForTesting static final Map<Class<?>, Constructor<? extends Unbinder>> BINDINGS = new LinkedHashMap<>();
|
ButterKnife生成类的路径:
Build -> intermediates -> classes -> debug -> com…
在build.gradle文件里可以看到这个自定义注解处理器,项目中是找不到这个文件的
annotationProcessor ‘com.jakewharton:butterknife-compiler:8.8.1’
ButterKnife-Compiler源码地址
手写IOC框架
首先声明自定义注解.
1 2 3 4 5 6 7 8 9 10 11 12
| @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface EventViewById { int value(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface EventOnClick { int[] value(); }
|
然后通过反射找到自定义的注入属性并且获取自定义属性上面的值,通过反射将找到的View注入属性中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
@android.annotation.TargetApi(24) private static void injectField(ViewFinder viewFinder, Object object) { Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { EventViewById bindViewById = field.getAnnotation(EventViewById.class); if (bindViewById != null) { int viewId = bindViewById.value(); View view = viewFinder.findViewById(viewId); if (view != null) { try { field.setAccessible(true); field.set(object, view); } catch (IllegalAccessException ex) { ex.toString(); } } } } }
|
注入事件以及绑定点击事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
@android.annotation.TargetApi(24) private static void injectEvent(ViewFinder viewFinder, Object object) { Class clazz = object.getClass(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { EventOnClick clickEvent = method.getDeclaredAnnotation(EventOnClick.class); if (clickEvent != null) { int[] viewIds = clickEvent.value(); if (viewIds.length > 0) { for (int viewId : viewIds) { View view = viewFinder.findViewById(viewId); boolean isCheckNet = method.getAnnotation(EventCheckNet.class) != null; if (view != null) { view.setOnClickListener(new DeclaredOnClickListener(method, isCheckNet, object)); } } } } } } private static class DeclaredOnClickListener implements View.OnClickListener {
private Method mMethod; private Object mHandlerType; private boolean mIsNet;
public DeclaredOnClickListener(Method method, boolean isNet, Object object) { this.mMethod = method; this.mHandlerType = object; this.mIsNet = isNet; }
@Override public void onClick(View view) { if (mIsNet) { if (!isNetworkConnected(view.getContext())) { Toast.makeText(view.getContext(), "no net", Toast.LENGTH_SHORT).show(); return; } }
try { mMethod.setAccessible(true); mMethod.invoke(mHandlerType, view); } catch (Exception e) { e.printStackTrace(); } } }
|
上一篇:VR App开发 小记
下一篇:热更新 AndFix 源码解析