package com.cheng.multithreadstudy.sunframework.proxy; import com.android.dx.stock.ProxyBuilder; import com.cheng.multithreadstudy.sunframework.proxy.filter.InterceptorFilter; import com.cheng.multithreadstudy.sunframework.proxy.callback.Interceptor; import com.cheng.utils.Logger; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Enhancer<T> implements InvocationHandler { private Interceptor[] callBacks; private InterceptorFilter filter; private Class<T> superClazz; private Class<?>[] constructorArgTypes; private Object[] constructorArgValues; private File mCacheDir; /** * @param superClazz 构造函数需要的class */ Enhancer(File cacheFileDir, Class<T> superClazz) { this.superClazz = superClazz; this.mCacheDir = cacheFileDir; } /** * @param superClazz * @param clazzes * @param args */ Enhancer(File cacheFileDir, Class<T> superClazz, Class<?>[] clazzes, Object[] args) { this(cacheFileDir, superClazz); this.constructorArgTypes = clazzes; this.constructorArgValues = args; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (filter == null) { return null; } int accept = filter.accept(method); if (accept >= callBacks.length) { return null; } if (method.getName().equals("hashCode") || method.getName().equals("toString")) { return ProxyBuilder.callSuper(proxy, method, args); } return callBacks[accept].intercept(proxy, method, args); } public void setCacheDir(File file) { this.mCacheDir = file; } /* * */ public void addCallBacks(Interceptor[] callBacks) { this.callBacks = callBacks; } /** * @param filter */ public void addFilter(InterceptorFilter filter) { this.filter = filter; } /** * 生成代理 * * @return */ public T create() { ProxyBuilder<T> proxy = ProxyBuilder.forClass(superClazz); if (constructorArgTypes != null && constructorArgValues != null && constructorArgValues.length == constructorArgTypes.length) { proxy.constructorArgTypes(constructorArgTypes).constructorArgValues(constructorArgValues); } proxy.handler(this); proxy.dexCache(mCacheDir); try { return proxy.build(); } catch (IOException e) { Logger.i("app", "error" + e.getClass() + ""); e.printStackTrace(); } return null; } }