android:Retrofit+RxJava的优雅封装
image.png
前言
Retrofit
和RxJava
已经出来很久了,很多前辈写了很多不错的文章,在此不得不感谢这些前辈无私奉献的开源精神,能让我们站在巨人的肩膀上望得更远。
Retrofit:Retrofit是Square 公司开发的一款针对Android 网络请求的框架。
RxJava:RxJava 是一个链式调用的异步框架。
RxJava在 GitHub 主页上的自我详情是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,概括得非常精准。
一言以辟之,就是让异步操作变得非常简单。
各自职责:Retrofit 负责请求的数据和请求的结果,使用接口的方式呈现,OkHttp 负责请求的过程,RxJava 负责异步,各种线程之间的切换。
RxJava
的使用参考–>给 Android 开发者的 RxJava 详解Retrofit
的使用参考–>Android Retrofit 2.0使用
本文内容是基于Retrofit + RxJava
做的少量优雅的封装。参考了很多文章加入了少量自己的了解,请多指教。
先引入依赖
build.gradle
// Okhttp库 implementation 'com.squareup.okhttp3:okhttp:3.11.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1' // Retrofit库 implementation 'com.squareup.retrofit2:retrofit:2.1.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' //RxJava implementation 'io.reactivex.rxjava2:rxjava:2.0.1' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
简单使用
1、先写一个接口Service
interface APIService { @GET("user/login" ) Call<UserInfo> login(@Query("username") String username,@Query("password")String password);}
2、获取Call执行网络请求
Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_URL) .build(); APIService service = retrofit.create(APIService.class); Call<UserInfo> call = service.login("张晓宇", "is sb"); call.enqueue(new Callback<UserInfo>() { @Override public void onResponse(Call<UserInfo> call, Response<UserInfo> response) { //请求成功 } @Override public void onFailure(Call<UserInfo> call, Throwable t) { //请求失败 } });
以上就是Retrofit的简单使用。但是实际项目中,我们一定不会这么写,这样写完全不符合我们写代码的优雅性和简洁性。所以,我们要对它进行优雅的封装。
Retrofit+RxJava优雅的封装
1、请求实体类与返回实体类的封装
BaseRequestEntity.java
public class BaseRequestEntity <T>{ private HeaderEntity header; private T data; public HeaderEntity getHeader() { return header; } public void setHeader(HeaderEntity header) { this.header = header; } public T getData() { return data; } public void setData(T data) { this.data = data; }}
BaseResponseEntity.java
public class BaseResponseEntity<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; }}
2、请求接口服务类封装
ObservableAPI.java
/** * 接口服务 **/public interface ObservableAPI { /** * 登录 */ @POST(URL.URL_LOGIN) Observable<BaseResponseEntity<LoginResponseEntity>> login(@Body BaseRequestEntity<LoginRequestEntity> requestEntity);}
3、ObservableManager封装(请求接口传参封装)
ObservableManager.java
public class ObservableManager { private static class SingletonHolder { static final ObservableManager INSTANCE = new ObservableManager(); } public static ObservableManager getInstance() { return ObservableManager.SingletonHolder.INSTANCE; } /** * login */ public BaseRequestEntity<LoginRequestEntityl> getLoginRequestEntity() { BaseRequestEntity<LoginRequestEntity> requestModel = new BaseRequestEntity<>(); requestModel.setHeader(HeaderUtils.setHeaderModel()); LoginRequestEntity loginRequestModel = new LoginRequestEntity(); requestModel.setData(loginRequestModel); return requestModel; }}
4、Retrofit封装
RetrofitHandler.java
public class RetrofitHandler { private static Retrofit mRetrofit; private static OkHttpClient mOkHttpClient; private static RetrofitHandler mRetrofitHandler; private static ObservableAPI mObservableAPI; private RetrofitHandler() { initRetrofit(); } public static synchronized RetrofitHandler getInstance() { if (mRetrofitHandler == null) { synchronized (RetrofitHandler.class) { if (mRetrofitHandler == null) { mRetrofitHandler = new RetrofitHandler(); } } } return mRetrofitHandler; } /** * 获取 Retrofit */ private void initRetrofit() { initOkHttpClient(); mRetrofit = new Retrofit.Builder() .baseUrl(URL.BASE_URL) //JSON转换器,使用Gson来转换 .addConverterFactory(GsonConverterFactory.create()) //RxJava适配器 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .client(mOkHttpClient) .build(); mObservableAPI = mRetrofit.create(ObservableAPI.class); } /** * 单例模式获取 OkHttpClient */ private static void initOkHttpClient() { if (mOkHttpClient == null) { synchronized (RetrofitHandler.class) { if (mOkHttpClient == null) { // 指定缓存路径,缓存大小100Mb Cache cache = new Cache(new File(HttpConfig.DIR_CACHE_FILE, "HttpCache"), 1024 * 1024 * 100); mOkHttpClient = new OkHttpClient.Builder() //设置连接超时时间 .connectTimeout(HttpConfig.HTTP_TIME_OUT_TIME, TimeUnit.SECONDS) //设置读取超时时间 .readTimeout(HttpConfig.HTTP_TIME_OUT_TIME, TimeUnit.SECONDS) //设置写入超时时间 .writeTimeout(HttpConfig.HTTP_TIME_OUT_TIME, TimeUnit.SECONDS) //默认重试一次 .retryOnConnectionFailure(true) //增加请求头阻拦器 .addInterceptor(InterceptorHelper.getHeaderInterceptor()) //增加日志阻拦器 .addInterceptor(InterceptorHelper.getLogInterceptor()) //增加缓存阻拦器 .addInterceptor(InterceptorHelper.getCacheInterceptor()) //增加重试阻拦器 .addInterceptor(InterceptorHelper.getRetryInterceptor()) // 信任Https,忽略Https证书验证 // https认证,假如要使用https且为自己设置证书 可以去掉这两行注释,并自行配制证书。 .sslSocketFactory(SSLSocketTrust.getSSLSocketFactory()) .hostnameVerifier(SSLSocketTrust.getHostnameVerifier()) //缓存 .cache(cache) .build(); } } } } /** * 对外提供调用 API的接口 * * @return */ public ObservableAPI getAPIService() { return mObservableAPI; }}
5、阻拦器封装(请求头阻拦器、日志阻拦器、缓存阻拦器、重试阻拦器等)
InterceptorHelper.java
/** * @author wy * @description 阻拦器工具类 */public class InterceptorHelper { public static String TAG = "Interceptor"; /** * 日志阻拦器 */ public static HttpLoggingInterceptor getLogInterceptor() { return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { Log.w(TAG, "LogInterceptor---------: " + message); } }).setLevel(HttpLoggingInterceptor.Level.BODY);//设置打印数据的级别 } /** * 缓存阻拦器 * * @return */ public static Interceptor getCacheInterceptor() { return new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); //CONTEXT不能为空 if (!NetworkUtils.isConnected(PalApplication.getInstance().getApplicationContext())) { int maxStale = 4 * 7 * 24 * 60; // 离线时缓存保存4周,单位:秒 CacheControl tempCacheControl = new CacheControl.Builder() .onlyIfCached() .maxStale(maxStale, TimeUnit.SECONDS) .build(); request = request.newBuilder() .cacheControl(tempCacheControl) .build(); } return chain.proceed(request); } }; } /** * 重试阻拦器 * * @return */ public static Interceptor getRetryInterceptor() { return new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { int maxRetry = 10;//最大重试次数 int retryNum = 5;//如果设置为3次重试的话,则最大可能请求4次(默认1次+3次重试) Request request = chain.request(); Response response = chain.proceed(request); while (!response.isSuccessful() && retryNum < maxRetry) { retryNum++; response = chain.proceed(request); } return response; } }; } /** * 请求头阻拦器 * * @return */ public static Interceptor getHeaderInterceptor() { return new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { //在这里你可以做少量想做的事,比方token失效时,重新获取token //或者者增加header等等 Request originalRequest = chain.request(); if (null == originalRequest.body()) { return chain.proceed(originalRequest); } Request compressedRequest = originalRequest.newBuilder() .header("Content-Encoding", "gzip") .header("User-Agent", "OkHttp Headers.java") .addHeader("Accept", "application/json; q=0.5") .addHeader("Accept", "application/vnd.github.v3+json") .addHeader("Accept-Encoding", "identity")// .addHeader(Constants.WEB_TOKEN, webi_token) .build(); Response proceed = chain.proceed(compressedRequest); return proceed; } }; }}
6、BaseObserver封装(请求失败、网络异常、接口错误、加载窗口等解决)
BaseObserver.java
public abstract class BaseObserver<T> implements Observer<BaseResponseEntity<T>> { protected Context mContext; public BaseObserver() { } public BaseObserver(Context cxt) { this.mContext = cxt; } @Override public void onSubscribe(Disposable d) { onRequestStart(); } @Override public void onNext(BaseResponseEntity<T> tBaseEntity) { onRequestEnd(); String message_common = "Oops, something went wrong. Please try again."; if (tBaseEntity.getErrorCode()==0) {//成功 try { onSuccess(tBaseEntity); } catch (Exception e) { e.printStackTrace(); } } else { try { if (!CommonUtils.isEmptyOrNull(tBaseEntity.getErrorMsg())) { onFailure(tBaseEntity.getErrorMsg()); } else { onFailure(message_common); } } catch (Exception e) { e.printStackTrace(); } } } @Override public void onError(Throwable e) { onRequestEnd(); String message_common = "Oops, something went wrong. Please try again."; String msg_timeout = "Oops, connection timeout, please try again later"; try { if (e instanceof ConnectException || e instanceof TimeoutException || e instanceof NetworkErrorException || e instanceof UnknownHostException) { onFailure(msg_timeout); } else { onFailure(message_common); } } catch (Exception e1) { e1.printStackTrace(); } } @Override public void onComplete() { } /** * 返回成功 * * @param tBaseEntity */ protected abstract void onSuccess(BaseResponseEntity<T> tBaseEntity); /** * 返回失败 * * @param errorMessage */ protected abstract void onFailure(String errorMessage); /** * 请求开始 */ protected void onRequestStart() { showProgressDialog(); } /** * 请求结束 */ protected void onRequestEnd() { closeProgressDialog(); } /** * 加载弹窗 */ public void showProgressDialog() { } /** * 关闭加载弹窗 */ public void closeProgressDialog() { }}
7、调度类封装
RxTransformerHelper.java
/** * 调度类 */public class RxTransformerHelper { public static <T> ObservableTransformer<T, T> observableIO2Main(final Context context) { return new ObservableTransformer<T, T>() { @Override public ObservableSource<T> apply(Observable<T> upstream) { return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()); } }; }}
8、使用方式
private void login() { RetrofitHandler.getInstance().getAPIService() .login(ObservableManager.getInstance().getLoginRequestEntity()) .compose(RxTransformerHelper.<BaseResponseEntity<LoginResponseModel>>observableIO2Main(this)) .subscribe(new BaseObserver<LoginResponseModel>() { @Override protected void onSuccess(BaseResponseEntity<LoginResponseModel> responseEntity) { showSuccessDialog("Success"); } @Override protected void onFailure(String errorMessage) { showErrorDialog(errorMessage); } }); }
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » android:Retrofit+RxJava的优雅封装
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » android:Retrofit+RxJava的优雅封装