面向切面编程(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. 网络耗时



原创粉丝点击