美文网首页网络随笔-生活工作点滴
简单封装Retrofit2+Rxjava2+OkHttp3

简单封装Retrofit2+Rxjava2+OkHttp3

作者: liliLearn | 来源:发表于2019-07-08 13:38 被阅读82次

    一、需要添加的依赖包

        // Retrofit+OKHttp  
        implementation 'com.squareup.retrofit2:retrofit:2.5.0'
        implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
        implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
        implementation 'com.squareup.okhttp3:okhttp:3.14.2'
        implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
        //RxJava2
        implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
        implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
        //AutoDispose
        implementation 'com.uber.autodispose:autodispose-android-archcomponents:1.3.0'
    

    二、基础使用

    website

    public interface ApiService {
        @GET("article/list/{page}/json")
        Call<BaseResponse<ArticleList>> getArticle(@Path("page") int pageNo);
    }
    
     Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://www.wanandroid.com")
                    .build();
    
            ApiService service = retrofit.create(ApiService.class);
    
     service.getArticle(1)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<BaseResponse<ArticleList>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(BaseResponse<ArticleList> articleListBaseResponse) {
    
                        }
    
                        @Override
                        public void onError(Throwable e) {
    
                        }
    
                        @Override
                        public void onComplete() {
    
                        }
                    });
    

    三、Retrofit封装

    public class ApiClient {
        private static final String BASE_URL = "https://www.wanandroid.com";
        private static final int TIMEOUT_CONNECTION = 30;
        private static final int TIMEOUT_READ = 60;
        private static final int TIMEOUT_WRITE = 60 * 3;
        private static ApiClient mInstance;
        private Retrofit mRetrofit;
    
    
        private ApiClient() {
            initialize();
        }
    
        public static ApiClient getInstance() {
            if (mInstance == null) {
                synchronized (ApiClient.class) {
                    if (mInstance == null) {
                        mInstance = new ApiClient();
                    }
                }
            }
            return mInstance;
        }
    
        public void initialize() {
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(initClient())
                    .build();
    
        }
    
        private OkHttpClient initClient() {
            Interceptor interceptor = chain -> {
                Request.Builder requestBuilder = chain.request().newBuilder();
                requestBuilder.addHeader("test", "test");
                return chain.proceed(requestBuilder.build());
            };
    
    
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS) //连接超时
                    .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS) //读取超时
                    .writeTimeout(TIMEOUT_WRITE, TimeUnit.SECONDS) //写入超时
                    .addInterceptor(interceptor)
                    .retryOnConnectionFailure(true); //断线重连
    
            //Log信息拦截器
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
            builder.addInterceptor(loggingInterceptor);
    
            return builder.build();
        }
    
        public <T> T create(Class<T> clazz) {
            return mRetrofit.create(clazz);
        }
    
        public UserService getApiService() {
            return mRetrofit.create(UserService.class);
        }
    }
    

    四、线程切换

    public final class RxScheduler {
    
        public static <T> ObservableTransformer<T, T> io2Main() {
            return upstream -> upstream
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
        }
    }
    

    五、统一处理结果

    public class BaseResponse<T> {
        private int errorCode;
        private String errorMsg;
        private T data;
    
        public int getErrorCode() {
            return errorCode;
        }
    
        public void setErrorCode(int errorCode) {
            this.errorCode = errorCode;
        }
    
        public String getErrorMsg() {
            return errorMsg;
        }
    
        public void setErrorMsg(String errorMsg) {
            this.errorMsg = errorMsg;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    }
    

    Service中使用

        @GET("data")
        Observable<BaseResponse<Data> getData();
        
        @GET("datas/{page}")
        Observable<BaseResponse<List<Data>>> getDatas(@Path("page") int pageNo);
    

    六、统一错误处理和结果处理

    网络错误可以大致分为两种,一种是网络请求中的错误、一种是服务器返回的业务错误。下面简称网络错误和业务错误,我们需要把网络错误转换成可对用户提示的错误。

    
    /**
     * 业务异常类型
     * 把网络错误转换成业务错误
     */
    public enum NetworkErrorType {
        BAD_GATEWAY(500, R.string.service_error),
        NOT_FIND(404, R.string.service_error),
        NETWORK_NOT_CONNECT(300, R.string.offline_error),
        UNEXPECTED_ERROR(301, R.string.parse_error),
        UNKNOWN_ERROR(304, R.string.unknown_error),
        TIMEOUT_ERROR(504, R.string.timeout_error);
    
        private final int code;
        private final int messageId;
    
        public int getCode() {
            return code;
        }
    
        public int getMessageId() {
            return messageId;
        }
    
    
        NetworkErrorType(int code, @StringRes int messageId) {
            this.code = code;
            this.messageId = messageId;
        }
    
        public NetworkErrorModel getErrorModel() {
            return new NetworkErrorModel(code, App.getInstance().getString(messageId));
        }
    }
    
    /**
     * 网络错误对象
     */
    public class NetworkErrorModel {
        private int code;
        private String message;
    
        public NetworkErrorModel(int code, String string) {
            this.code = code;
            this.message = string;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getMessage() {
            return message;
        }
    }
    
    final class UnifiedErrorUtil {
    
        static NetworkErrorType handlerError(Throwable e) {
            NetworkErrorType networkErrorType;
            if (e instanceof UnknownHostException) {
                networkErrorType = NetworkErrorType.NETWORK_NOT_CONNECT;
            } else if (e instanceof SocketTimeoutException) {
                networkErrorType = NetworkErrorType.TIMEOUT_ERROR;
            } else if (e instanceof ConnectException) {
                networkErrorType = NetworkErrorType.NETWORK_NOT_CONNECT;
            } else if (e instanceof SSLHandshakeException) {
                networkErrorType = NetworkErrorType.NETWORK_NOT_CONNECT;
            } else {
                networkErrorType = NetworkErrorType.UNKNOWN_ERROR;
            }
            return networkErrorType;
        }
    }
    
    public abstract class ResponseObserver<T extends BaseResponse> implements Observer<T> {
        public static final int SUCCESS_CODE = 0;
    
        public abstract void success(T t);
    
        public abstract void failure(int statusCode, NetworkErrorModel networkErrorModel);
    
        @Override
        public void onSubscribe(Disposable d) {
            showLoading();
        }
    
        @Override
        public void onNext(T t) {
            success(t);
        }
    
        @Override
        public void onError(Throwable e) {
            cancelLoading();
            NetworkErrorType networkErrorType = UnifiedErrorUtil.handlerError(e);
            failure(networkErrorType.getCode(), networkErrorType.getErrorModel());
        }
    
        @Override
        public void onComplete() {
            cancelLoading();
        }
    
        private void showLoading() {
            // Do not implement
        }
    
        private void cancelLoading() {
            // Do not implement
        }
    }
    

    七、自动取消订阅

    使用RxJava发布一个订阅后,当Activity被finish,此时订阅逻辑还未完成,如果没有及时取消订阅,就会导致Activity无法被回收,从而引发内存泄漏。

    我们使用AutoDispose 来解决Rxjava 泄露问题。
    前提:

    • 需要先将项目迁移至AndroidX
    • 依赖Android Architecture Components中的Lifecycle 框架,需要Support Library 26.1.0 及其以后的版本
    public final class AutoDisposeHelp {
    
        public static <T> AutoDisposeConverter<T> bindAutoDispose(LifecycleOwner owner) {
            return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(owner, Lifecycle.Event.ON_DESTROY));
        }
    }
    
    

    八、其他

    最后使用效果,只是一个简单的封装,需要其他更多的需求大家自己扩展。

     ApiClient.getInstance().getApiService().fetchRequestVinylList(0)
                    .compose(RxScheduler.io2Main())
                    .as(AutoDisposeHelp.bindAutoDispose(this))
                    .subscribe(new ResponseObserver<BaseListMessage>() {
    
                        @Override
                        public void success(BaseListMessage baseListMessage) {
                            if (baseListMessage.getErrorCode() == SUCCESS_CODE) {
                                //服务器成功
                            } else {
                                //服务器业务错误
                            }
                        }
    
                        @Override
                        public void failure(int statusCode, NetworkErrorModel networkErrorModel) {
                            Toast.makeText(MainActivity.this, networkErrorModel.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
    

    相关文章

      网友评论

        本文标题:简单封装Retrofit2+Rxjava2+OkHttp3

        本文链接:https://www.haomeiwen.com/subject/aruohctx.html