dim.red
#背景 android 的中设置监听有两种.
一种 setOnXXListener (eg View.setOncClickListener()) .
一种 addOnXXXListener (TextView.addTextWatchListener()); 两种的区别是第一种内部只会保存一个listener, 每次调用就是覆盖. 第二种内部会保存一个List, 每次调用的时候就是添加一个监听器.
定义 1 2 3 4 5 public interface OnStatusListener { void onChange(); void onChange1(); void onChange2(); }
优化前 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 public class StastusManager { private List<OnStatusListener> onStatusListeners = new ArrayList<>(); public void addOnStastusListener(OnStatusListener onStatusListener) { onStatusListeners.add(onStatusListener); } public void removeOnStatusListener(OnStatusListener onStatusListener) { onStatusListeners.remove(onStatusListener); } public void onChange() { for (OnStatusListener onStatusListener : onStatusListeners) { onStatusListener.onChange(); } } public void onChange1() { for (OnStatusListener onStatusListener : onStatusListeners) { onStatusListener.onChange1(); } } public void onChange2() { for (OnStatusListener onStatusListener : onStatusListeners) { onStatusListener.onChange2(); } } }
当接口方法多了以后, 相似代码就变更多了. 我们使用动态代理 优化一下相似代码
优化后 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class StastusManager { private DynamicInterface<OnStatusListener> onStatusListeners = DynamicFactory.newObject(OnStatusListener.class); public void addOnStastusListener(OnStatusListener onStatusListener) { onStatusListeners.addT(onStatusListener); } public void removeOnStatusListener(OnStatusListener onStatusListener) { onStatusListeners.removeT(onStatusListener); } public void onChange() { onStatusListeners.castT().onChange(); } public void onChange1() { onStatusListeners.castT().onChange1(); } public void onChange2() { onStatusListeners.castT().onChange2(); } }
优化以后没有了 List 类和每次的 for 循环. 现在还不能感觉到这个方式的好处. 当你有大量的 addXXlistener 你会发现, 比起之前的方式. 这种更加的优雅. 下面是实现的关键代码1 2 3 4 5 6 7 8 9 10 11 12 13 /** * Created by dim on 2017/12/16. */ @Keep public interface DynamicInterface<T extends Object> { void addT(T t); void removeT(T t); T castT(); }
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 /** * Created by dim on 2017/12/16. */ public class DynamicFactory { public static <T> DynamicInterface<T> newObject(final Class<T> cls) { if (!cls.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } if (cls.getInterfaces().length > 0) { throw new IllegalArgumentException("API interfaces must not extend other interfaces."); } return (DynamicInterface<T>) Proxy.newProxyInstance(cls.getClassLoader(), new Class<?>[]{cls, DynamicInterface.class}, new InvocationHandler() { private List<T> list = new ArrayList<>(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("addT") || method.getName().equals("removeT")) { if (args != null && args.length == 1 && cls.isInstance(args[0])) { if (method.getName().equals("addT")) { list.add((T) args[0]); } else if (method.getName().equals("removeT")) { list.remove((T) args[0]); } return null; } } if (method.getName().equals("castT") && args == null) { return proxy; } Class<?> returnType = method.getReturnType(); if (returnType.isAssignableFrom(boolean.class)) { boolean object = true; for (T t : list) { if (!(boolean) method.invoke(t, args)) { object = false; } } return object; } else if (returnType.isAssignableFrom(Boolean.class)) { Boolean object = Boolean.TRUE; Boolean temp; for (T t : list) { if ((temp = (Boolean) method.invoke(t, args)) != null && !temp) { object = Boolean.FALSE; } } return object; } else if (returnType.isAssignableFrom(Void.class) || returnType.isAssignableFrom(void.class)) { for (T t : list) { method.invoke(t, args); } return null; } else { throw new IllegalArgumentException("returnType must boolean Boolean Void void"); } } }); } }