retrofit如何配合Rxjava封裝程式碼
如何使用Retrofit+RxJava框架的簡單封裝使用
掌握之前需要了解以下知識相關知識
上述文章只是講了一下基本的原理,那麼在實際應用裡的如何和RXJAVA配合使用呢
一、怎麼搭配Rxjava使用
我們知道,在使用retrofit的時候可以配置網路請求、日誌、執行緒的介面卡,其中有一個方法addCallAdapterFactory,這個方法就是為我們新增rxjava執行緒排程的介面卡。
//建立Retrofit物件
mRetrofit = new Retrofit
.Builder()
.client(mOkHttpClientBuilder.build())
.baseUrl(host)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
如果我們不進行配置那麼系統會為我們提供一個預設的介面卡defaultCallAdapterFactory
*/
public Retrofit build() {
...........
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
...........
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
在這裡層層走下去,會給我們返回一個Response的物件,在實際業務裡,我們需要利用rxjava來進行一些請求的封裝,實現整體程式碼架構更加簡潔
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
所以引入了rxjava的封裝,好在retrofit也是支援這種新增,我們加入了RxJava2CallAdapterFactory,最後封裝返回了一個Observable的觀察者物件。
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
這就是我們使用rxjava的原理,為什麼可以使用以及使用後返回了什麼
當前我們有一個api
public interface ApiService {
//獲取使用者資訊
@POST(RetrofitManager.ACCOUNT)
Observable<TextUserInfo> getTextUserInfo(@Body UserInfoRequest userInfoRequest);
}
第一步 :呼叫獲得observable物件
Observable<TextUserInfo> observable = RetrofitManager.getInstance(activity).create(ApiService.class).
getTextUserInfo(updateUserInfoRequest).map((new HttpResultFunc<TextUserInfo>()));
RetrofitManager封裝對retrofit的初始化,包括對rxjava的執行緒新增,
create就是呼叫retrofit的create,貼上部分程式碼
public class RetrofitManager {
/**
* 單例模式,建立RetrofitManager物件
*/
public static RetrofitManager getInstance(Context activity) {
if (instance == null) {
synchronized (RetrofitManager.class) {
instance = new RetrofitManager(activity);
}
}
// instance.setRsa();
return instance;
}
private RetrofitManager(Context context) {
File cacheFile = new File(context.getCacheDir(), "cache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); //50Mb
mOkHttpClientBuilder = new OkHttpClient.Builder();
mOkHttpClientBuilder.connectTimeout(CONNECT_OUTTIME, TimeUnit.MILLISECONDS);
mOkHttpClientBuilder.readTimeout(CONNECT_OUTTIME, TimeUnit.MILLISECONDS);
mOkHttpClientBuilder.writeTimeout(CONNECT_OUTTIME, TimeUnit.MILLISECONDS);
mOkHttpClientBuilder.retryOnConnectionFailure(true);
//Logger攔截器,設定列印等級,可以列印請求日誌
if (LogUtils.LOG_FLAG) {
mHttpLoggingInterceptor = new HttpLoggingInterceptor();
mHttpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
mOkHttpClientBuilder.addInterceptor(mHttpLoggingInterceptor);
}
//設定公共攔截器
mHttpCommonInterceptorBuilder = new HttpCommonInterceptor.Builder();
try {
mHttpCommonInterceptorBuilder
.addHeaderParams("xd-version-name", OSUtils.getVersionCodeName(context))
.addHeaderParams("xd-version-code", OSUtils.getVersionCode(context) + "")
.addHeaderParams("xd-agent", "Android");
} catch (Exception e) {
e.printStackTrace();
}
setAccessToken();
mOkHttpClientBuilder.addInterceptor(mHttpCommonInterceptorBuilder.build());
mOkHttpClientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
// 以攔截到的請求為基礎建立一個新的請求物件,然後插入Header
Request request = null;
try {
request = chain.request().newBuilder()
.addHeader("antiKey", RsaKeyUtil.encryptByPublicKey(CLIENT_SECRET + ":" + System.currentTimeMillis(), PUBLIC_KEY))
.addHeader("xd-request-id", RsaKeyUtil.createRandomCharData(6))
.build();
if (BuildConfig.DEBUG) {
Log.e("TAG", "請求頭==" + request.headers().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
// 開始請求
return chain.proceed(request);
}
});
//設定快取攔截器
mHttpCacheInterceptor = new HttpCacheInterceptor();
gson = new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).serializeNulls().create();
mOkHttpClientBuilder.addNetworkInterceptor(mHttpCacheInterceptor);
mOkHttpClientBuilder.cache(cache);
//建立Retrofit物件
mRetrofit = new Retrofit
.Builder()
.client(mOkHttpClientBuilder.build())
.baseUrl(host)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
private void setRsa() {
try {
mHttpCommonInterceptorBuilder.addHeaderParams("antiKey", RsaKeyUtil.encryptByPublicKey(CLIENT_SECRET + ":" + System.currentTimeMillis(), PUBLIC_KEY));
} catch (Exception e) {
e.printStackTrace();
}
}
public void setAccessToken() {
String token = Paper.book().read("access_token");
if (!TextUtils.isEmpty(token)) {
mHttpCommonInterceptorBuilder.addHeaderParams("authorization", "bearer " + token);
} else {
mHttpCommonInterceptorBuilder.addHeaderParams("authorization", "");
}
}
public <T> T create(Class<T> service) {
if (api == null) {
T t = mRetrofit.create(service);
api = t;
}
return (T) api;
}
/**
* rx訂閱 rx1.0的
*/
// public <T> void toSubscribe(Observable<T> o, Subscriber<T> s) {
// o.subscribeOn(Schedulers.io())
// .unsubscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe(s);
// }
/**
* rx訂閱 rx2.0的
*/
public <T> void toSubscribe(Observable<T> o, DisposableObserver disposableObserver) {
o.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(disposableObserver);
}
//如果需要存在依賴關係請求使用map或者flatmap
}
create我們知道是呼叫了動態代理,serviceMethod.adapt就是呼叫了RxJava2CallAdapter的adapt,返回了oservable的物件
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
通過map裡面的攔截,我們又可以對返回的引數進行定製化的操作,使其能夠適配不同型別的引數返回,如何排程,請參考rxjava的內容,使用map,在apply裡面進行操作.
至此,獲得了應有的物件
二:使用rxjava開啟執行緒排程
建立被觀察者執行緒
DisposableObserver disposable = new ProgressSubscriber<Bean>(new SubscriberOnResponseListenter<Bean>() {
@Override
public void next(Bean bean) {
baseView.getNetWorkSuccess(Bean);
}
@Override
public void error(String e) {
baseView.showError(e);
}
}, activity, false);
RetrofitManager.getInstance(activity).toSubscribe(observable, disposable);
/**
* rx訂閱 rx2.0的
*/
public <T> void toSubscribe(Observable<T> o, DisposableObserver disposableObserver) {
o.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(disposableObserver);
}
其實到這裡基本就結束了,我們拿到了網路請求引數的回撥,在這種結構裡,將網路請求,引數設定,方法呼叫完全分開,適用於mvp mvc ,mvvc等各種解耦性質的架構設計.
最後,記得使用完要解綁訂閱者
public class BasePresenter<V> {
private CompositeDisposable mCompositeDisposable;
private WeakReference<V> mViewRef;
public void attachModelView(V pView) {
mViewRef = new WeakReference<>(pView);
}
public V getView() {
if (isAttach()) {
return mViewRef.get();
} else {
return null;
}
}
private boolean isAttach() {
return null != mViewRef && null != mViewRef.get();
}
//增加訂閱者
protected void addSubscrebe(Disposable disposable) {
if (null == mCompositeDisposable) {
mCompositeDisposable = new CompositeDisposable();
}
mCompositeDisposable.add(disposable);
}
//解綁訂閱者
public void unSubscribe() {
if (null != mCompositeDisposable) {
mCompositeDisposable.clear();
}
}
}
相關文章
- Android實現Rxjava2+Retrofit完美封裝AndroidRxJava封裝
- Retrofit+okhttp+Rxjava封裝網路請求工具類HTTPRxJava封裝
- RxJava + Retrofit原始碼解析RxJava原始碼
- Retrofit + RxJavaRxJava
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝(一)Android架構MVP模式RxJava封裝
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之多Url(七)Android架構MVP模式RxJava封裝
- Retrofit的簡單封裝封裝
- Android RxJava系列三: 與Retrofit2結合使用和封AndroidRxJava
- Android中Retrofit的封裝使用Android封裝
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之檔案下載(二)Android架構MVP模式RxJava封裝
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之斷點下載(五)Android架構MVP模式RxJava封裝斷點
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之檔案上傳(三)Android架構MVP模式RxJava封裝
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之常見問題(四)Android架構MVP模式RxJava封裝
- 擁抱RxJava(二):Observable究竟如何封裝資料?RxJava封裝
- Retrofit2<三> rxJava 分析RxJava
- 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之資料預處理(六)Android架構MVP模式RxJava封裝
- Retrofit2+RxJava 簡單使用RxJava
- Retrofit+Rxjava的資料請求RxJava
- Kotlin中Retrofit網路請求簡單封裝Kotlin封裝
- python程式碼怎麼封裝Python封裝
- openresty+redis配合 lua指令碼封停 IPRESTRedis指令碼
- RxJava+Retrofit2搭建網路請求元件完整配置、示例程式碼及流程梳理RxJava元件
- Rxjava2與Retrofit2的使用RxJava
- 我們真的需要使用RxJava+Retrofit嗎?RxJava
- OkHttp、rxJava、Retrofit聯合網路請求(二)HTTPRxJava
- OkHttp、rxJava、Retrofit聯合網路請求(一)HTTPRxJava
- Android專案框架搭建:mvp+retrofit+rxjava+rxbusAndroid框架MVPRxJava
- 使用Retrofit+RxJava實現網路請求RxJava
- 程式碼改變世界 | 如何封裝一個簡單的 Koa封裝
- axios的二次封裝與async,await的配合使用?iOS封裝AI
- 使用Retrofit+RxJava實現帶進度下載RxJava
- 讓我的專案也使用RxJava+OkHttp+RetrofitRxJavaHTTP
- Retrofit + Kotlin + MVVM 的網路請求框架的封裝嘗試KotlinMVVM框架封裝
- 小程式如何封裝提示元件並且使用封裝元件
- 分分鐘使用Retrofit+Rxjava實現網路請求RxJava
- java封裝繼承以及多型(含程式碼)Java封裝繼承多型
- OkHttp+Retrofit+Dagger2+RxJava+MVP架構 學習筆記HTTPRxJavaMVP架構筆記
- 淺入深出Vue:程式碼整潔之封裝Vue封裝