RxJava2+retrofit实现网络封装

一.Rxjava2也出来了一段时间了,这段时间项目就用了一下Rxjava2和retrofit来实现了网络封装,考虑到可能存在的不为人知的bug,广大技术宅也可以提出改进意见共同进步,博主QQ:1129126470,WeChat:ym1129126470 申请请注明来意,欢迎技术交流吐槽,转载请注明出处谢谢。
二.好了废话不多说了下面给出代码不吝赐教
1.依赖库

    compile 'com.squareup.retrofit2:retrofit:2.0.0'
    compile 'com.squareup.retrofit2:converter-jackson:2.0.0'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0-RC3'
    compile 'io.reactivex.rxjava2:rxjava:2.0.0-RC3'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.0-RC1'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okio:okio:1.8.0'

2.ApiInterface接口封装

public interface ApiInterface{
    Retrofit getRetrofit();

     T getClientApi(Class cls);
}

3.网络检查

public class AppClient {

    public final static boolean isNetworkReady(final Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        if (ni != null) {
            return ni.isConnected();
        }
        return false;
    }

    public final static boolean isMobileConnected(final Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();

        if ((null != ni) && ni.isConnected()) {
            return ConnectivityManager.TYPE_MOBILE == ni.getType();
        }

        return false;
    }


}

4.缓存处理

public class CacheApi implements ApiInterface {
    private static Retrofit retrofit = null;
    private volatile static CacheApi cacheApi;

    private CacheApi() {
    }

    public static CacheApi getInstance() {
        if (cacheApi == null) {
            synchronized (CacheApi.class) {
                if (cacheApi == null) {
                    cacheApi = new CacheApi();
                }
            }
        }
        return cacheApi;
    }

    @Override
    public Retrofit getRetrofit() {
        if (retrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.connectTimeout(15, TimeUnit.SECONDS);
            builder.readTimeout(15, TimeUnit.SECONDS);
            builder.writeTimeout(15, TimeUnit.SECONDS);
            //错误重连
            builder.retryOnConnectionFailure(true);
            File cacheFile = new File(MvpContactApplication.getInstance().getExternalCacheDir(), "MybCache");
            Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
            Interceptor cacheInterceptor = chain -> {
                Request request = chain.request();
                if (!AppClient.isNetworkReady(MvpContactApplication.getInstance())) {
                    request = request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }
                Response response = chain.proceed(request);
                if (AppClient.isNetworkReady(MvpContactApplication.getInstance())) {
                    int maxAge = 0;
                    // 有网络时 设置缓存超时时间0个小时
                    response.newBuilder()
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            //.removeHeader("")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
                            .build();
                } else {
                    // 无网络时,设置超时为4周
                    int maxStale = 60 * 60 * 24 * 28;
                    response.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            //.removeHeader("nyn")
                            .build();
                }
                return response;
            };
            builder.cache(cache).addInterceptor(cacheInterceptor);
            //以上设置结束,才能build(),不然设置白搭
            OkHttpClient okHttpClient = builder.build();
            retrofit = new Retrofit.Builder()
                    .baseUrl(Constant.BASE_URL)
                    .client(okHttpClient)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(StringConverterFactory.create())
                    .build();
        }
        return retrofit;
    }

    @Override
    public  T getClientApi(Class cls) {
        Retrofit retrofit = getRetrofit();
        return retrofit.create(cls);
    }
}

5.DisposableBeanSubscriber

public abstract class DisposableBeanSubscriber extends DisposableSubscriber {
    private Class cls;
    private Context context;
    private LoadingDialog loadingDialog;
    private boolean decode;

    public DisposableBeanSubscriber() {
    }

    public DisposableBeanSubscriber(Context context, Class cls) {
        this.cls = cls;
        this.context = context;
        loadingDialog = new LoadingDialog(context);
        showDialog();
    }

    public DisposableBeanSubscriber(Context context, Class cls, boolean decode) {
        this.cls = cls;
        this.context = context;
        loadingDialog = new LoadingDialog(context);
        showDialog();
        this.decode = decode;
    }

    public void showDialog() {
        loadingDialog.show();
    }

    public void dismissDialog() {
        loadingDialog.close();
    }

    @Override
    public void onNext(Object object) {

        if (decode) {
            LogUtils.e(context, "onNext: --------decode:" + object.toString());
            iNext(new Gson().fromJson(CodeUtil.voteDecode(object.toString()), cls));

        } else {
            LogUtils.e(context, "onNext: ---------------" + object.toString());
            iNext(new Gson().fromJson(object.toString(), cls));
        }
    }

    @Override
    public void onError(Throwable t) {
        iError();
    }

    @Override
    public void onComplete() {
        iComplete();
    }

    protected abstract void iNext(T t);

    protected void iError() {
        Tos.t(context, Constant.CONNECT_ERROR);
        dismissDialog();
    }

    protected void iComplete() {
        dismissDialog();
    }
}

6.正常的链接网络流程

public class NormalApi implements ApiInterface {
    private static Retrofit retrofit = null;
    private volatile static NormalApi normalApi;

    private NormalApi() {
    }

    public static NormalApi getInstance() {
        if (normalApi == null) {
            synchronized (NormalApi.class) {
                if (normalApi == null) {
                    normalApi = new NormalApi();
                }
            }
        }
        return normalApi;
    }

    @Override
    public Retrofit getRetrofit() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(15, TimeUnit.SECONDS);
        builder.readTimeout(15, TimeUnit.SECONDS);
        builder.writeTimeout(15, TimeUnit.SECONDS);
        builder.retryOnConnectionFailure(true);
        OkHttpClient okHttpClient = builder.build();
        retrofit = new Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)
                .client(okHttpClient)
                .addConverterFactory(StringConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        return retrofit;
    }

    @Override
    public  T getClientApi(Class t) {
        Retrofit retrofit = getRetrofit();
        return retrofit.create(t);
    }
}

7.下面借助我耿哥封装的思路封装StringConverterFactory

public class StringConverterFactory extends Converter.Factory {

    public static StringConverterFactory create() {
        return new StringConverterFactory();
    }

    private StringConverterFactory() {

    }

    @Override
    public Converter responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {
        return new StringResponseBodyConverter();
    }

    @Override
    public Converter requestBodyConverter(Type type,
                                                          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return new StringRequestBodyConverter();
    }
}

8.请求封装StringRequestBodyConverter

public class StringRequestBodyConverter  implements Converter<String, RequestBody> {
    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
    private static final Charset UTF_8 = Charset.forName("UTF-8");

    StringRequestBodyConverter() {
    }

    @Override public RequestBody convert(String value) throws IOException {
        Buffer buffer = new Buffer();
        Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
        writer.write(value);
        writer.close();
        return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
    }
}

9.响应

public class StringResponseBodyConverter implements Converter<ResponseBody, String> {
    @Override
    public String convert(ResponseBody value) throws IOException {
        try {
            return value.string();
        } finally {
            value.close();
        }
    }
}

10RxBus相关(相当于EventBus时间总线)

public class RxBus {
    //相当于Rxjava1.x中的Subject
    private final FlowableProcessor mBus;
    private static volatile RxBus sRxBus = null;

    private RxBus() {
        //调用toSerialized()方法,保证线程安全
        mBus = PublishProcessor.create().toSerialized();
    }

    public static synchronized RxBus getDefault() {
        if (sRxBus == null) {
            synchronized (RxBus.class) {
                if (sRxBus == null) {
                    sRxBus = new RxBus();
                }
            }
        }
        return sRxBus;
    }


    /**
     * 发送消息
     * @param o
     */
    public void post(Object o) {
        new SerializedSubscriber<>(mBus).onNext(o);
    }

    /**
     * 确定接收消息的类型
     * @param aClass
     * @param 
     * @return
     */
    public  Flowable toFlowable(Class aClass) {
        return mBus.ofType(aClass);
    }

    /**
     * 判断是否有订阅者
     * @return
     */
    public boolean hasSubscribers() {
        return mBus.hasSubscribers();
    }
}

11.RxBusHelper的封装

public class RxBusHelper {
    /**
     * 发布消息
     *
     * @param o
     */
    public static void post(Object o) {
        RxBus.getDefault().post(o);
    }

    /**
     * 接收消息,并在主线程处理
     *
     * @param aClass
     * @param disposables 用于存放消息
     * @param listener
     * @param 
     */
    public static  void doOnMainThread(Class aClass, CompositeDisposable disposables, OnEventListener listener) {
        disposables.add(RxBus.getDefault().toFlowable(aClass).observeOn(AndroidSchedulers.mainThread()).subscribe(listener::onEvent, throwable -> listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS))));
    }

    public static  void doOnMainThread(Class aClass, OnEventListener listener) {
        RxBus.getDefault().toFlowable(aClass).observeOn(AndroidSchedulers.mainThread())
                .subscribe(listener::onEvent, throwable ->
                        listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS)));
    }

    /**
     * 接收消息,并在子线程处理
     *
     * @param aClass
     * @param disposables
     * @param listener
     * @param 
     */
    public static  void doOnChildThread(Class aClass, CompositeDisposable disposables, OnEventListener listener) {
        disposables.add(RxBus.getDefault().toFlowable(aClass).subscribeOn(Schedulers.newThread()).subscribe(listener::onEvent, throwable -> listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS))));
    }

    public static  void doOnChildThread(Class aClass, OnEventListener listener) {
        RxBus.getDefault().toFlowable(aClass).subscribeOn(Schedulers.newThread()).subscribe(listener::onEvent, throwable -> listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS)));
    }

    public interface OnEventListener {
        void onEvent(T t);

        void onError(ErrorBean errorBean);
    }
}

有什么指教的,请留言或者私信给我,我看到了及时回复。

你可能感兴趣的:(Android,随笔)