RxJava2和Retrofit2封裝教程(整潔、簡單、實用)
前言
RxJava2與Retrofit2是老搭檔了,之前寫了一篇《RxJava和Retrofit2的統(tǒng)一處理單個請求》,是用的Rxjava1.0,本次使用Rxjava2.0與Retrofit2進行封裝,一樣整潔、簡單、實用。Rxjava2相比Rxjava1優(yōu)化和改動不少了東西,網(wǎng)上有很多大神寫的文章,這里就不粘貼復(fù)制了。封裝的過程有什么問題、疑問,請在下方留言。
下面話不多說了,來一起看看詳細的介紹吧
封裝教程如下:
核心網(wǎng)絡(luò)請求:
package com.lin.netrequestdemo.data; import android.util.Log; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.functions.Consumer; import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; public class RxNet { /** * 統(tǒng)一處理單個請求 * * @param observable * @param callBack * @param <T> */ public static <T> Disposable request(Observable<BaseResponse<T>> observable, final RxNetCallBack<T> callBack) { return observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .onErrorReturn(new Function<Throwable, BaseResponse<T>>() { @Override public BaseResponse<T> apply(Throwable throwable) { Log.e("LinNetError", throwable.getMessage()); callBack.onFailure(ExceptionHandle.handleException(throwable)); return null; } }) .subscribe(new Consumer<BaseResponse<T>>() { @Override public void accept(BaseResponse<T> tBaseResponse) { if (tBaseResponse.getCode().equals("200")) { callBack.onSuccess(tBaseResponse.getData()); } else { callBack.onFailure(tBaseResponse.getMsg()); } } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) { Log.e("LinNetError", "單個請求的錯誤" + throwable.getMessage()); } }); } /** * 統(tǒng)一處理單個請求 * 返回數(shù)據(jù)沒有body */ public static Disposable requestWithoutBody(Observable<BaseResponse> observable, final RxNetCallBack<String> callBack) { return observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .onErrorReturn(new Function<Throwable, BaseResponse>() { @Override public BaseResponse apply(Throwable throwable) { Log.v("LinNetError", throwable.getMessage()); callBack.onFailure(ExceptionHandle.handleException(throwable)); return null; } }) .subscribe(new Consumer<BaseResponse>() { @Override public void accept(BaseResponse baseResponse) { if (baseResponse.getCode().equals("200")) { callBack.onSuccess(baseResponse.getMsg()); } else { callBack.onFailure(baseResponse.getMsg()); } } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) { Log.v("LinNetError", "單個請求的錯誤:沒有body" + throwable.getMessage()); } }); } }
回調(diào)就是普通的泛型的回調(diào)
package com.lin.netrequestdemo.data; public interface RxNetCallBack<T> { /** * 數(shù)據(jù)請求成功 * * @param data 請求到的數(shù)據(jù) */ void onSuccess(T data); /** * 數(shù)據(jù)請求失敗 */ void onFailure(String msg); }
錯誤異常處理(可能不全):
package com.lin.netrequestdemo.data; import android.net.ParseException; import com.google.gson.JsonParseException; import org.apache.http.conn.ConnectTimeoutException; import org.json.JSONException; import java.net.ConnectException; import retrofit2.HttpException; public class ExceptionHandle { private static final int UNAUTHORIZED = 401; private static final int FORBIDDEN = 403; private static final int NOT_FOUND = 404; private static final int REQUEST_TIMEOUT = 408; private static final int INTERNAL_SERVER_ERROR = 500; private static final int BAD_GATEWAY = 502; private static final int SERVICE_UNAVAILABLE = 503; private static final int GATEWAY_TIMEOUT = 504; public static String handleException(Throwable e) { String errorMsg; if (e instanceof HttpException) { HttpException httpException = (HttpException) e; switch (httpException.code()) { case UNAUTHORIZED: case FORBIDDEN: case NOT_FOUND: case REQUEST_TIMEOUT: case GATEWAY_TIMEOUT: case INTERNAL_SERVER_ERROR: case BAD_GATEWAY: case SERVICE_UNAVAILABLE: default: errorMsg = "網(wǎng)絡(luò)錯誤"; break; } return errorMsg + ":" + httpException.code(); } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) { return "解析錯誤"; } else if (e instanceof ConnectException) { return "連接失敗"; } else if (e instanceof javax.net.ssl.SSLHandshakeException) { return "證書驗證失敗"; } else if (e instanceof ConnectTimeoutException) { return "連接超時"; } else if (e instanceof java.net.SocketTimeoutException) { return "連接超時"; } else { return "未知錯誤"; } } }
然后就是ApiManager:
package com.lin.netrequestdemo.data.api; import android.util.Log; import com.lin.netrequestdemo.data.AppConstants; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; public class ApiManager { private Retrofit client; private ApiManager() { client = new Retrofit.Builder() .baseUrl(AppConstants.Base_Url_Test) .client(initClient()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); } private static volatile MallApi INSTANCE; public static MallApi getInstance() { if (INSTANCE == null) { synchronized (ApiManager.class) { if (INSTANCE == null) { INSTANCE = new ApiManager().getMallApi(); } } } return INSTANCE; } private MallApi getMallApi() { return client.create(MallApi.class); } private static OkHttpClient initClient() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); //聲明日志類 HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { Log.v("LinNet", message); } }); //設(shè)定日志級別 httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); //延時 builder.addInterceptor(httpLoggingInterceptor) .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS); return builder.build(); } }
怎么用:
showLoading(); Map<String, String> map = new ArrayMap<>(); map.put("action", "pricetrend"); addCompositeDisposable(RxNet.request(ApiManager.getInstance().getCat(map), new RxNetCallBack<List<CatBean>>() { @Override public void onSuccess(List<CatBean> data) { hideLoading(); showToast("獲取列表成功" + data.get(0).toString()); } @Override public void onFailure(String msg) { hideLoading(); showToast(msg); } }));
Demo奉上 https://github.com/FriendLin/NetRequestDemo(本地下載)
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
Android使用原生組件WebView加載網(wǎng)頁和數(shù)據(jù)的方法
這篇文章主要介紹了Android使用原生組件WebView加載網(wǎng)頁和數(shù)據(jù)的方法的相關(guān)資料,需要的朋友可以參考下2016-09-09Android 文件存儲與SharedPreferences存儲方式詳解用法
SharedPreferences是安卓平臺上一個輕量級的存儲類,用來保存應(yīng)用的一些常用配置,比如Activity狀態(tài),Activity暫停時,將此activity的狀態(tài)保存到SharedPereferences中;當Activity重載,系統(tǒng)回調(diào)方法onSaveInstanceState時,再從SharedPreferences中將值取出2021-10-10解決android studio 打開java文件 內(nèi)容全變了的問題
這篇文章主要介紹了解決android studio 打開java文件 內(nèi)容全變了的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03android Bitmap圓角與倒影的具體實現(xiàn)代碼
android Bitmap圓角與倒影的具體實現(xiàn)代碼,需要的朋友可以參考一下2013-06-06Android編程實現(xiàn)圖片放大縮小功能ZoomControls控件用法實例
這篇文章主要介紹了Android編程實現(xiàn)圖片放大縮小功能ZoomControls控件用法,結(jié)合具體實例形式分析了Android ZoomControls控件實現(xiàn)圖片縮放的具體操作方法與相關(guān)注意事項,需要的朋友可以參考下2017-09-09Android App開發(fā)中RecyclerView控件的基本使用教程
這篇文章主要介紹了Android App開發(fā)中RecyclerView控件的基本使用教程,RecyclerView在Android 5.0之后伴隨著Material Design出現(xiàn),管理布局方面十分強大,需要的朋友可以參考下2016-04-04Android自定義View實現(xiàn)鐘擺效果進度條PendulumView
這篇文章主要介紹了Android自定義View實現(xiàn)鐘擺效果進度條PendulumView,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09