面向切面编程(aop),实现Android网络请求
来源:互联网 发布:淘宝订单号查询 编辑:程序博客网 时间:2024/06/05 23:40
在项目中使用了百度语音功能打开sdk发现了一个面向切面的支持包(aop)。由于代码被混淆过看起来着实痛苦,通过大胆猜测和验证终于将代码复原并为我所用。aop的代码思路是通过反射执行代理对象已注册的方法,在方法前遍历所有的拦截器,通过验证拦截器的返回值判断是否执行次方法,如果执行在方法后遍历所有的拦截器。在执行网络请求之前我们要判断网络是否可用、 是否重复请求、弹出加载框、打印参数结果日志,而在这里我将它们定义为4种拦截器。
1. NewWorkInterceptor 网络拦截器
2. RepeatInterceptor 重复拦截器
3. ProgressDialogInterceptor 对话框拦截器(不拦截,只加载)
4. HttpLogInterceptor 日志拦截器(不拦截,值打印参数、结果、耗时)
代码:先贴aop代码
过滤器
public interface IInterceptor { /** * 方法执行前 * * @param proxy * @param method * @param args * @return */ Object before(Object proxy, Method method, Object[] args); /** * 方法执行后 * * @param proxy * @param method * @param args * @param methodReturn * @return */ Object after(Object proxy, Method method, Object[] args, Object methodReturn);}拦截器处理者
public interface IInterceptorHandler extends InvocationHandler { /** * 注册多个方法 */ void registerMethods(); /** * 注册一个方法 * @param methodName */ void registerMethod(String methodName); /** * 注销一个方法 * @param methodName */ void unregisterMethod(String methodName); /** * 是否拦截 * @param methodName * @return */ boolean canIntercept(String methodName); /** * 绑定 * @param proxied * @param interceptors * @return */ Object bind(Object proxied, List<IInterceptor> interceptors);}代理工厂
public interface IProxyFactory<T> { /** * 创建被代理对象 * * @return */ T createProxied(); /** * 拦截器处理对象 * * @return */ IInterceptorHandler createInterceptorHandler(); /** * 创建拦截器集合 * * @return */ List<IInterceptor> createInterceptors(); /** * 执行代理 * * @return */ T makeProxy();}抽象拦截器
public abstract class AInterceptor implements IInterceptor { public static final String TAG = "HttpLog"; protected List<String> methods = new ArrayList(); public AInterceptor() { this.addMetodName(); } @Override public Object before(Object proxied, Method method, Object[] args) { return this.isAdd(method.getName()) ? this.interceptor(proxied, method, args) : AInterceptorHandler.DEFAULT; } @Override public Object after(Object proxied, Method method, Object[] args, Object methodReturn) { return AInterceptorHandler.DEFAULT; } private boolean isAdd(String methodName) { return methods.contains(methodName); } protected abstract void addMetodName(); protected abstract Object interceptor(Object proxied, Method method, Object[] args);}抽象拦截器处理者
public abstract class AInterceptorHandler implements IInterceptorHandler { public static final Object DEFAULT = Integer.valueOf(0); public static final Object END = Integer.valueOf(1); protected List<IInterceptor> interceptors; protected Object proxied; protected List<String> methodNames = new ArrayList(); public AInterceptorHandler() { } @Override public Object bind(Object proxied, List<IInterceptor> interceptors) { this.proxied = proxied; this.interceptors = interceptors; Class clazz = this.proxied.getClass(); Object proxy = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this); Log.d("AInterceptorHandler", "proxy=" + proxy); return proxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); boolean canIntercept = this.canIntercept(methodName); if (canIntercept) { Object result = null; Object beforeResult = this.before(this.proxied, method, args); if (beforeResult.equals(END)) { return result; } else { result = method.invoke(this.proxied, args); Object afterResult = this.after(this.proxied, method, args, result); Log.d("AInterceptorHandler", "afterResult=" + afterResult); return result; } } else { return method.invoke(this.proxied, args); } } @Override public void registerMethod(String methodName) { if (methodName != null) { this.methodNames.add(methodName); } } @Override public void unregisterMethod(String methodName) { if (methodName != null) { this.methodNames.remove(methodName); } } @Override public boolean canIntercept(String methodName) { return this.methodNames.contains(methodName); } protected Object before(Object proxy, Method method, Object[] args) { Object result = DEFAULT; int size = this.interceptors.size(); for (int i = 0; i < size; ++i) { result = this.interceptors.get(i).before(proxy, method, args); if (result.equals(END)) { return result; } } return result; } protected Object after(Object proxy, Method method, Object[] args, Object methodReturn) { Object result = DEFAULT; int size = this.interceptors.size(); for (int i = size - 1; i >= 0; --i) { result = this.interceptors.get(i).after(proxy, method, args, methodReturn); } return result; }}下面是网络请求部分
网络拦截器
public class NetWorkInterceptor extends AInterceptor { @Override protected void addMetodName() { methods.add("requestPost"); methods.add("requestGet"); } @Override protected Object interceptor(Object proxied, Method method, Object[] args) { IDataProvider dataProvider = DataProviderManager.getDataProvider(); if (dataProvider.getNetType() == NetState.NETWORN_NONE) { T.ToastShort("当前无网络,请检查网络设置"); return AInterceptorHandler.END; } return AInterceptorHandler.DEFAULT; }}重复拦截器
public class RepeatInterceptor extends AInterceptor { private List<String> urlList; private boolean interceptor; public RepeatInterceptor() { urlList = Collections.synchronizedList(new ArrayList()); } @Override protected void addMetodName() { methods.add("requestPost"); methods.add("requestGet"); } @Override public Object before(Object proxied, Method method, Object[] args) { if (!Util.isEmpty(args)) { String url = args[0].toString(); if (urlList.contains(url)) { interceptor = true; } else { interceptor = false; urlList.add(url); } } return super.before(proxied, method, args); } @Override protected Object interceptor(Object proxied, Method method, Object[] args) { String url = args[0].toString(); if (interceptor) { L.d(TAG, "过滤重复请求" + url); return AInterceptorHandler.END; } return AInterceptorHandler.DEFAULT; } @Override public Object after(Object proxied, Method method, Object[] args, Object methodReturn) { if (!Util.isEmpty(args)) { String url = args[0].toString(); urlList.remove(url); } return super.after(proxied, method, args, methodReturn); }}对话框拦截器
public class ProgressDialogInterceptor extends AInterceptor { private DialogHelper mDialogHelper; private SimpleHttpCallback callback; @Override protected void addMetodName() { methods.add("requestPost"); methods.add("requestGet"); } @Override protected Object interceptor(Object proxied, Method method, Object[] args) { return AInterceptorHandler.DEFAULT;//不做拦截 } @Override public Object before(Object proxied, Method method, Object[] args) { if (mDialogHelper != null) { mDialogHelper.showLoadingProgressDialog(); } if (args[2] != null && args[2] instanceof SimpleHttpCallback) { callback = (SimpleHttpCallback) args[2]; } return super.before(proxied, method, args); } @Override public Object after(Object proxied, Method method, Object[] args, Object methodReturn) { if (callback != null) { callback.addResult(new SimpleHttpCallback.IResult() { @Override public void result(String data) { if (mDialogHelper != null) { mDialogHelper.dismissProgressDialog(); } } }); } else { if (mDialogHelper != null) { mDialogHelper.dismissProgressDialog(); } } return super.after(proxied, method, args, methodReturn); } public void setDialogHelper(DialogHelper dialogHelper) { this.mDialogHelper = dialogHelper; }}日志拦截器
public class HttpLogInterceptor extends AInterceptor { /** * 开始时间 */ private long beginTime; private SimpleHttpCallback callback; @Override protected void addMetodName() { methods.add("requestPost"); methods.add("requestGet"); } @Override protected Object interceptor(Object proxied, Method method, Object[] args) { return AInterceptorHandler.DEFAULT; //不做拦截 } @Override public Object before(Object proxied, Method method, Object[] args) { beginTime = System.currentTimeMillis(); if (!Util.isEmpty(args)) { //打印url L.d(TAG, "url:" + args[0].toString() + "\n"); //打印参数 if (args[1] != null) { Map<String, String> map = (Map) args[1]; for (Map.Entry<String, String> entry : map.entrySet()) { L.d(TAG, " "+entry.getKey() + " : " + entry.getValue()); } } //请求回调 if (args[2] != null && args[2] instanceof SimpleHttpCallback) { callback = (SimpleHttpCallback) args[2]; } } return super.before(proxied, method, args); } @Override public Object after(Object proxied, Method method, Object[] args, Object methodReturn) { if (callback != null) { callback.addResult(new SimpleHttpCallback.IResult() { @Override public void result(String data) { L.d(TAG, "result:" + data); L.d(TAG, " 网络耗时 : " + (System.currentTimeMillis() - beginTime) / 1000f + " 秒 "); } }); } return super.after(proxied, method, args, methodReturn); }}拦截器处理者
public class HttpHandler extends AInterceptorHandler { @Override public void registerMethods() { methodNames.add("requestPost"); methodNames.add("requestGet"); }}拦截器工厂
public class HttpFactory extends AProxyFactory<AiJuHttp> { private ArrayList interceptors = new ArrayList(); private HttpHandler mHttpHandler; private ProgressDialogInterceptor mDialogInterceptor; private static volatile HttpFactory instance; public static HttpFactory getInstance() { if (instance == null) { synchronized (HttpFactory.class) { if (instance == null) { instance = new HttpFactory(); } } } return instance; } private HttpFactory() { mHttpHandler = new HttpHandler(); mHttpHandler.registerMethods(); mDialogInterceptor = new ProgressDialogInterceptor(); //网络拦截 interceptors.add(new NetWorkInterceptor()); //重复请求拦截 interceptors.add(new RepeatInterceptor()); //不拦截,加入加载对话框 interceptors.add(mDialogInterceptor); //不拦截,加入打印参数、返回值、耗时日志 interceptors.add(new HttpLogInterceptor()); } public void setDialogHelper(DialogHelper dialogHelper) { if (mDialogInterceptor != null) { mDialogInterceptor.setDialogHelper(dialogHelper); } } @Override public AiJuHttp createProxied() { return AiJuHttpProxy.getInstance(); } @Override public IInterceptorHandler createInterceptorHandler() { return mHttpHandler; } @Override public List<IInterceptor> createInterceptors() { return interceptors; }}这里有很多项目封装的类,功能大家都知道的代码就不贴出了。
DateProviderManager 项目基础信息
L 日志打印工具类
T 吐司工具类
DialogHelper 对话框工具类
AjJuHttpProxy 网络请求代理类隔离第三组件
这里贴出日志打印结果:1.url 2. 参数 3. 结果 4. 网络耗时
阅读全文
0 0
- 面向切面编程(aop),实现Android网络请求
- C++ 实现 AOP(面向切面编程)
- Android面向切面编程(AOP)
- Android面向切面编程(AOP)
- Android面向切面(AOP)编程实战
- Aop(面向切面编程)
- 面向切面编程(AOP)
- AOP(面向切面编程)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- AOP(面向切面编程)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- AOP (面向切面编程)
- 安卓学习笔记---实现简易播放器(带有进度条,开始与结束时间,暂停与播放)
- Android长按Button按钮,产生涟漪效果
- Html标签使用实例
- 数据库通用函数的使用
- SQL中Charindex和Oracle中对应的函数Instr
- 面向切面编程(aop),实现Android网络请求
- 达内课程-二维数组和变量
- bugku MISC 隐写2 wirteup
- CentOs7.3下搭建LAMP环境(Apache2.4 + Mysql5.7 + PHP5.6 + Laravel5.2)
- 关于 Wi-Fi 你所不知道的 8 件事
- 利用代理模式隔离Android第三方组件(图片加载库,网络库)
- bzoj 3517: 翻硬币
- STM32的can现场总线实验心得
- kmalloc/kfree,vmalloc/vfree函数用法和区别