如何優雅地取消Retrofit請求?
在實際開發中,頁面關閉,取消請求是很常見的需求,這裡分享一種簡單的實現方法。 我的思路是把網路請求和上下文的生命週期繫結。這裡用用到了Rxjava的Subject,Subject 既是 Observable 又是 Observer(Subscriber)。既可以發訊息也可以接收訊息。
我首先定義了幾個列舉,對應上下文的生命週期。
public enum ActivityLifeCycleEvent { CREATE,START,RESUME,PAUSE,STOP,DESTROY } 複製程式碼
以Fragment
為例,在BaseFragment
中,相應的生命週期回撥中發射訊息。
import rx.subjects.PublishSubject; public abstract class BaseFragment extends Fragment { protected final PublishSubject<ActivityLifeCycleEvent> lifecycleSubject = PublishSubject.create(); @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); } @Override public void onPause() { super.onPause(); lifecycleSubject.onNext(ActivityLifeCycleEvent.PAUSE); } @Override public void onStop() { super.onStop(); lifecycleSubject.onNext(ActivityLifeCycleEvent.STOP); } @Override public void onResume() { super.onResume(); lifecycleSubject.onNext(ActivityLifeCycleEvent.RESUME); } @Override public void onDestroy() { super.onDestroy(); lifecycleSubject.onNext(ActivityLifeCycleEvent.DESTROY); } } 複製程式碼
一般情況下我們會使用Retrofit+Rxjava來進行網路請求,比如像下面這樣:
@Multipart @POST(Urls.TIMER_GETUSERDETAIL_RX) Observable<Results<User>> getUser(@PartMap Map<String, RequestBody> map); 複製程式碼
具體請求的時候可能是下面這樣
ApiService.instancce() .getUser(p.build()) .takeUntil(bindLifeCycle(lifecycleSubject,ActivityLifeCycleEvent.DESTROY)) .subscribe({ …… }) 複製程式碼
注意:下面這句話
.takeUntil(RxUtils.bindLifeCycle(lifecycleSubject, ActivityLifeCycleEvent.DESTROY)) 複製程式碼
takeUntil
一旦響應是成功它將自動終止源Observable於是停止向後端傳送資料。如果不是則繼續傳送請求。這裡如果收到ActivityLifeCycleEvent.DESTROY
訊息,就會停止向後端傳送資料。
public static Observable<ActivityLifeCycleEvent> bindLifeCycle(PublishSubject<ActivityLifeCycleEvent> lifecycleSubject, ActivityLifeCycleEvent bindEvent) { returnlifecycleSubject.takeFirst(activityLifeCycleEvent -> activityLifeCycleEvent.equals(bindEvent)); } 複製程式碼
嗯,就這麼多。下面就是愉快地使用吧~