面向切面编程(aop),实现Android网络请求

        在项目中使用了百度语音功能打开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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值