android 使用高级反射加代理实现网络请求层隔离

2022-05-26  本文已影响0人  背锅TV丶伴奏大师

前言:android网络请求框架日新月异,从之前的xUtils到现在的Retrofit,已变化很多,此时我有一个安卓项目在设计阶段要考虑换框架的需求我们该怎么快速切换呢,总不可能每个页面去慢慢的替换吧,所以就有了标题的解决方案。
直接上代码
1.ICallback

public interface ICallback {
    void onSuccess(String result);
    void onFail(String error);
}

2.IHttpProcessor

import java.util.Map;
//房产公司
public interface IHttpProcessor {
    void post(String url, Map<String,Object> params,ICallback callback);
}

3.HttpHelper

import java.util.Map;

//业务员
public class HttpHelper implements IHttpProcessor{
    private static HttpHelper instance;
    private HttpHelper(){}
    public static HttpHelper getInstance(){
        synchronized (HttpHelper.class){
            if(instance==null){
                instance=new HttpHelper();
            }
        }
        return instance;
    }

    private static IHttpProcessor mIHttpProcessor=null;
    public static void init(IHttpProcessor httpProcessor){
        mIHttpProcessor=httpProcessor;
    }

    @Override
    public void post(String url, Map<String, Object> params, ICallback callback) {
        mIHttpProcessor.post(url, params, callback);
    }
}

4.HttpCallback

import com.google.gson.Gson;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class HttpCallback<Result> implements ICallback {
    @Override
    public void onSuccess(String result) {
        Class<?> clz=analaysisClassInfo(this);
        Gson gson=new Gson();
        Result objResult=(Result) gson.fromJson(result,clz);
        onSuccessResult(objResult);
    }
    //模板方法
    public abstract void onSuccessResult(Result objResult);
    public abstract void onFailureResult(String error);
    private Class<?> analaysisClassInfo(Object object){
        Type type=object.getClass().getGenericSuperclass();
        Type[] types=((ParameterizedType)type).getActualTypeArguments();//得到的是Result
        return (Class<?>)types[0];
    }

    @Override
    public void onFail(String error) {
        onFailureResult(error);
    }
}

5.OkHttpProcessor,如果切换其他网络请求框架,需要自定义

import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
//业主,此处还可以用volley,xUtils,okGo等网络请求框架
public class OkHttpProcessor implements IHttpProcessor{
    private OkHttpClient okHttpClient;
    private Handler handler;
    public OkHttpProcessor(){
        okHttpClient=new OkHttpClient();
        handler=new Handler(Looper.myLooper());
    }
    @Override
    public void post(String url, Map<String, Object> params, ICallback callback) {
        RequestBody requestBody=appendBody(params);
        Request request=new Request.Builder().url(url).post(requestBody).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFail(e.getMessage());
                        //callback.onSuccess(result);
                    }
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                String result=response.body().string();
                if(response.isSuccessful()){
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onSuccess(result);
                        }
                    });
                }else {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onFail(result);
                        }
                    });
                }
            }
        });
    }
    private RequestBody appendBody(Map<String,Object> params){
        FormBody.Builder body=new FormBody.Builder();
        if(params==null||params.isEmpty()){
            return body.build();
        }
        for(Map.Entry<String,Object> entry:params.entrySet()){
            body.add(entry.getKey(),entry.getValue().toString());
        }
        return body.build();
    }
}

6.使用时:

//1.在application的oncreate()初始化
HttpHelper.init(new OkHttpProcessor());
//2.在需要调用的地方如下
     /**
     * 把new HttpCallback<String>中的string替换成服务端返回的模板类
     */
    private void getData(){
        String url="";
        Map<String,Object> params=new HashMap<>();
        params.put("key","value");
        HttpHelper.getInstance().post(url, params, new HttpCallback<String>() {
            @Override
            public void onSuccessResult(String objResult) {
                //do your thing
            }
            @Override
            public void onFailureResult(String error) {
                //do your thing
            }
        });
    }

后语:上文用的是静态代理模式,当然另外还有动态代理可以实现。

增加一个类如下:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//自动生产代理类
public class ProxyInvocationHandler implements InvocationHandler {
    private IHttpProcessor httpProcessor;
    /**
     * 调用目标对象的方法,可以在方法执行前后添加自己的操作
     * @param proxy 代理对象
     * @param method RealSubject对象中被Proxy调用的方法
     * @param args 被Proxy调用的方法参数列表
     * @return Proxy调用的方法的返回值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //我们可以在方法调用之前添加自己的操作
        System.out.println("before invoke");
        //调用RealSubject的方法
        Object result = method.invoke(this.httpProcessor, args);
        //我们可以在方法调用之后添加自己的操作
        System.out.println("after invoke");
        return result;
    }
    public Object getProxy(IHttpProcessor httpProcessor){
        this.httpProcessor = httpProcessor;
        // Proxy.newProxyInstance方法用来生成目标对象的代理类
        // 第一个参数是 目标对象的类加载器
        // 第二个参数是 目标对象的接口列表
        // 第三个参数是 InvocationHandler的实现类
        return Proxy.newProxyInstance(getClass().getClassLoader(),httpProcessor.getClass().getInterfaces(),this);
    }
}

使用时:

private fun getData(){
        val okHttpProcessor = OkHttpProcessor()
        val handler = ProxyInvocationHandler()
        val proxy = handler.getProxy(okHttpProcessor) as IHttpProcessor
        proxy.get(url, params, object : ICallback {
            override fun onSuccess(result: String) {
                Log.i("","")
            }
            override fun onFail(error: String) {
                Log.i("","")
            }
        })
    }

测试时可以去玩安卓平台找开放的API:https://www.wanandroid.com/blog/show/2

如果是okgo则增加OkGoProcessor

import android.app.Application;

import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.HttpParams;

import java.util.Map;

import okhttp3.Call;
import okhttp3.Response;

//业主,此处还可以用volley,xUtils,android-async-http,okGo等网络请求框架
public class OkGoProcessor implements IHttpProcessor{
    private ICallback callback;
    public OkGoProcessor(Application app){
        OkGo.init(app);
        OkGo.getInstance().debug("okgo");
    }
    @Override
    public void post(String url, Map<String, Object> params, ICallback callback) {
        this.callback=callback;
        OkGo.post(url).tag(url).params(convertParams(params)).execute(stringCallback);
    }

    @Override
    public void get(String url, Map<String, Object> params, ICallback callback) {
        this.callback=callback;
        OkGo.get(url).tag(url).params(convertParams(params)).execute(stringCallback);
    }
    private HttpParams convertParams(Map<String, Object> params){
        HttpParams httpParams=new HttpParams();
        for(Map.Entry<String,Object> entry:params.entrySet()){
            httpParams.put(entry.getKey(),entry.getValue().toString());
        }
        return httpParams;
    }
    private StringCallback stringCallback=new StringCallback() {
        @Override
        public void onSuccess(String s, Call call, Response response) {
            String result=response.body().toString();
            if(response.isSuccessful()){
                callback.onSuccess(result);
            }else {
                callback.onFail(result);
            }
        }
        @Override
        public void onError(Call call, Response response, Exception e) {
            super.onError(call, response, e);
            callback.onFail(e.getMessage());
        }
    };
}
上一篇 下一篇

猜你喜欢

热点阅读