RxJava2與Retrofit2 封裝(整潔、簡單、實用)
RxJava2與Retrofit2是老搭檔了,之前寫了一篇《RxJava和Retrofit2的統一處理單個請求》,是用的Rxjava1.0,本次使用Rxjava2.0與Retrofit2進行封裝,一樣整潔、簡單、實用。Rxjava2相比Rxjava1優化和改動不少了東西,網上有很多大神寫的文章,這裡就不貼上複製了。封裝的過程有什麼問題、疑問,請在下方留言,作者會一一回復。
核心網路請求:
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 { /** * 統一處理單個請求 * * @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()); } }); } /** * 統一處理單個請求 * 返回資料沒有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()); } }); } }
回撥就是普通的泛型的回撥
package com.lin.netrequestdemo.data; public interface RxNetCallBack<T> { /** * 資料請求成功 * * @param data 請求到的資料 */ void onSuccess(T data); /** * 資料請求失敗 */ 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 = "網路錯誤"; 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); } }); //設定日誌級別 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奉上ofollow,noindex">https://github.com/FriendLin/NetRequestDemo