先附上初始化Retrofit的工具類:
public class RetrofitProvide {
/**
* 網(wǎng)絡(luò)連接超時時間
*/
public static final int CONN_TIME_OUT = 60*1000;
/**
* 網(wǎng)絡(luò)讀取超時時間
*/
public static final int READ_TIME_OUT = 60*1000;
private volatile static Retrofit retrofit = null;
private RetrofitProvide(){}
public static Retrofit getInstance(){
if(retrofit == null){
synchronized (RetrofitProvide.class){
retrofit = getRetrofit();
}
}
return retrofit;
}
private static OkHttpClient getOkHttpClient(){
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//超時設(shè)置
builder.connectTimeout(CONN_TIME_OUT, TimeUnit.MILLISECONDS);
builder.readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS);
//日志
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
builder.addNetworkInterceptor(getInterceptor());
return builder.build();
}
private static Interceptor getInterceptor(){
return chain -> {
Request request = chain.request();
HttpUrl url;
//這里是每次app調(diào)接口都需要給的參數(shù)侠仇,統(tǒng)一放在這里
url = request.url().newBuilder()
.addQueryParameter("sessionToken", MyApp.getInstance().getSession())
.addQueryParameter("cityId",MyApp.getInstance().getCurrentCityId())
.addQueryParameter("appVersion",MyApp.getInstance().getAppVersionName())
.addQueryParameter("phoneAttributes",MyApp.getInstance().getPhoneAttributes())
.addQueryParameter("phoneType","android")
.build();
request = request.newBuilder().url(url).build();
LogUtils.LOGI("-- head 修改后",url.toString());
return chain.proceed(request);
};
}
/**
* 設(shè)置連接內(nèi)容
* json轉(zhuǎn)換
* Rxjava適配
* @return
*/
private static Retrofit getRetrofit(){
return new Retrofit
.Builder()
.baseUrl(NetConstant.SERVICE_URL.concat("/"))
.client(getOkHttpClient())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
}
通過這個工具類來初始化Retrofit蛤高,可以實現(xiàn)網(wǎng)址攔截,增加聯(lián)網(wǎng)參數(shù)或者打印網(wǎng)址都可以
直接使用:
RetrofitProvide.getInstance()
.create(NannyApi.class)
.getNannyDetail(nannyId)
.compose(RxSchedulers.io_main(mContext))
.subscribe(nannyDetail -> {
//TODO 拿到對象開始做事情
});
比如這個NannyApi,里面有個getNannyDetail的接口钓株,我們通過這個接口可以拿到保姆詳情的json數(shù)據(jù),然后這個.compose(RxSchedulers.io_main(mContext))是對切換線程和出現(xiàn)錯誤提示的懶人寫法陌僵,這里先給出RxSchedulers這個懶人類:
public class RxSchedulers {
public static <T> Observable.Transformer<T, T> io_main(Context context) {
return tObservable -> tObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.doOnError(new MyOnErrorAction1<>(context));
}
}
可以直觀的看到轴合,這個.io_main()方法非常簡單,就把.subscribeOn(Schedulers.io())被觀察者運行在io線程和.observeOn(AndroidSchedulers.mainThread())觀察者運行在主線程兩個線程切換加入碗短,并增加了一個獲取錯誤的類受葛,這個類繼承于Action1,把獲取到的錯誤用dialog來彈出偎谁,代碼比較簡單总滩,如下:
public class MyOnErrorAction1<T> implements Action1<T> {
public Dialog dialog;
private Context mContext;
public MyOnErrorAction1(Context context) {
mContext = context;
}
@Override
public void call(T t) {
if (t instanceof Throwable) {
Throwable throwable = (Throwable) t;
throwable.printStackTrace();
dialog = DialogUtil.showAlert(mContext, "異常消息", throwable.getMessage(), "知道了", false, view -> dialog.dismiss());
}
}
}
當然這里面大家也可以加入把錯誤提交到服務(wù)器等等一系列的操作
這樣我們在用Retrofit聯(lián)網(wǎng)時,不用操心錯誤處理和線程切換巡雨,專注于獲取到的數(shù)據(jù)闰渔,只需要加入.compose(RxSchedulers.io_main(mContext))這一行代碼,就可以直接訂閱一個Action1的onNext來操作數(shù)據(jù)了铐望,當然需要對onCompleted做操作的話冈涧,比如隱藏掉加載動畫,在 .doOnError()后面還可以加一個.doOnCompleted()正蛙,里面加入一個對操作完成之后的要做的Action0督弓。
有什么不懂的可以留言哦