Android网络层重构设计 Rx+Retrofit+okhttp

   公司app应用一直使用okhttp,虽然它确实好用,但是经年日久,使用时的不方便越来越多,比如重复代码过多,内存泄露不好控制,调用时参数过多等等。

   还是决定痛下杀手,早点除掉这个顽疾。

   So,有了这次网络层重新架构,感觉还算满意,现在列出一下过程:

   1、首选看一下对外公开的网络层工具 AppConnecter:

  /**网络层工具类*/
public class AppConnecter {
    public static int CONNNET_TIMEOUT = 30;         //超时设置
    private static AppConnecter appConnecter;       //单例对象
    private RequestInterface mServer;               //Retrofit2网络接口
    private String mInitServerUrl;                  //请求域名中的主机名 如https://m.test.com
    private final OkHttpClient client;              //实际的请求主体 OkHttpClient

     //初始化httpserver
    private AppConnecter() {
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); //创建OkHttpClient
        try {
            builder.sslSocketFactory(createSSLSocketFactory());         //创建httpsClient
            builder.hostnameVerifier(new TrustAllHostnameVerifier());
        } catch (Exception e) {
        }
        builder.connectTimeout(CONNNET_TIMEOUT, TimeUnit.SECONDS);      //设置网络超时
        builder.readTimeout(CONNNET_TIMEOUT, TimeUnit.SECONDS);
        builder.addInterceptor(new RequestInterceptor());               //OkHttp请求拦截器
        client = builder.build();
        mInitServerUrl = "https://m.test.com";
        mServer = getServer();
    }

    private RequestInterface getServer() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(mInitServerUrl)
                .client(client)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        return retrofit.create(RequestInterface.class);            //自定义的网络接口
    }

    public static AppConnecter getInsatnce() {                    //单例 不用多说
        if (appConnecter == null) {
            synchronized (AppConnecter.class) {
                if (appConnecter == null) {
                    appConnecter = new AppConnecter();
                }
            }
        }
        return appConnecter;
    }
    
    //用于切换网路请求的线程,observeOn是指定回调线程
    Observable.Transformer schedulersTransformer() {
        return new Observable.Transformer() {
            @Override
            public Observable call(Object observable) {
                return ((Observable) observable)
                        .subscribeOn(Schedulers.io())
                        .unsubscribeOn(Schedulers.io())
                        .observeOn(Schedulers.immediate());
            }
        };
    }

    /**
     * 发送Post请求
     */
    public Observable reqPostWithRx(String postUrl, Map postparams, PublishSubject lifecycleSubject) {
        if (postparams == null) {
            postparams = new HashMap<String, String>();
        }
        //防止内存创建的Observable,当call返回true的时候,终止rx的所有消息发送
        Observable<ActivityLifeCycleEvent> compareLifecycleObservable =
                lifecycleSubject.takeFirst(new Func1<Integer, Boolean>() {
                    @Override
                    public Boolean call(Integer integer) {
                        return integer.equals(ActivityLifeCycleEvent.STOP);
                    }
                });
        //发送请求
        return mServer.queryRxPostUrl(postUrl, postparams).compose(schedulersTransformer()).takeUntil(compareLifecycleObservable);
    }

    /**
     *发送Get请求
     */
    public Observable reqGetWithRx(String url, Map<String, String> params, PublishSubject lifecycleSubject) {
        if (params == null) {
            params = new HashMap<String, String>();
        }
        //防止内存创建的Observable,当call返回true的时候,终止rx的所有消息发送
        Observable<ActivityLifeCycleEvent> compareLifecycleObservable =
                lifecycleSubject.takeFirst(new Func1<Integer, Boolean>() {
                    @Override
                    public Boolean call(Integer integer) {
                        boolean isStop = integer.equals(ActivityLifeCycleEvent.STOP);
                        return isStop;
                    }
                });
        //发送请求
        return mServer.queryRxGetUrl(url, params).compose(schedulersTransformer()).takeUntil(compareLifecycleObservable);
    }

    这个类公布出来的就2个 : reqGetWithRx(用于get) reqPostWithRx (用于post)

    它们返回的对象都是 Observable (Rx的关键核心类),用它可以做一系列的不同操作,什么排序,过滤等等,你想怎么弄它就怎么弄。它就是发送网络请求后,服务端返回的结果。

    compareLifecycleObservable这个对象,十分关键,它就是为了防止我们android中经常容易犯错的那个内存泄露而设置的。我们在activity基类中统一新建lifecycleSubject。

    它在哪使用呢?

    就是在我们的本地界面activity finish的时候,

    public void finish() {
        lifecycleSubject.onNext(ActivityLifeCycleEvent.STOP);
        super.finish();

    }

    这样它就会帮我们把当前页面所有的请求filish掉,怎么样,省心吧!


2、接着我们来看看RequestInterceptor(请求拦截器)

    这个RequestInterceptor,其实是OkHttp自带的拦截器,我们只要继承okhttp3.Interceptor就可以了。

    然后覆盖它的intercept方法,在这个方法里,做一些针对URL的操作,比如编码,签名,加密等


3、然后就是RequestInterface,自定义的网络接口

public interface RequestInterface {

    //结合RxJava的Post请求
    @FormUrlEncoded
    @POST("{url}")
    Observable<String> queryRxPostUrl(@Path("url") String url, @FieldMap Map<String, String> params);

    //结合RxJava的get请求
    @GET("{url}")
    Observable<String> queryRxGetUrl(@Path("url") String url, @QueryMap Map<String,String> params);

}

这样调用的时候,我们传的参数,只需要 与功能相关的接口名称与参数了。


4、还需要定义一个Rx的网络回调订阅者Subscriber

    这个类主要是用于统一处理返回的字符串解析,我们给它加上泛型,就可以统一解析成需要的数据对象。

public abstract class BaseSubscriber<T> extends Subscriber {

   public final void onNext(final Object o) {
        String result = (String) o;
	//此处转换成我们需要的数据对象
        Type type = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        final T bean = JSON.parseObject(result, type);		//假定返回的数据是json格式
        ...
   onSuccess
   onFailed
   onError

5、最后我们统一在Activity的基类中增加通用方法

//BaseBean:自定义的数据对象基类
//ReqBean:自定义的网络请求参数对象
public <T extends BaseBean> void reqByGet(ReqBean reqBean, BaseSubscriber<T> reqCallBack) {
	AppConnecter.getInsatnce().queryGetWithRx(reqBean.url, reqBean.getLastParams(), lifecycleSubject)
		.subscribe(reqCallBack);
}


做了这么多,终于到了享受的时候了,很简单,一句代码搞定:

  String url = "/test/test.do";
  reqByGet(new ReqBean(url, new String[][]{{"参数1", "参数值"}}), new BaseSubscriber<XxxBean>(){
            @Override
            public void onSuccess(XxxBean sKeyBean) {
                //此处处理相关业务
            }


            @Override
            public void onFailed(String code, String msg) {
		//错误处理
            }
        });

大功告成了~~~~!

(但其实它还是有明显的问题,大家有没有发现呢?

  就是返回的Observable,是依赖第三方框架的,这个东东要是以后替换或者升级时,Rx改动了它,那就麻烦大了

所以,最好的办法是自定义一个接口,来包装Observable)

©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页