Rxjava结合Retrofit,如何优雅的取消请求!

kkman777 8年前
   <p style="text-align:center"><img src="https://simg.open-open.com/show/6b7fe233091eabae35f38983a6fa9d6e.jpg"></p>    <p>前几篇主要介绍了retrofit基本使用,结合rxJava的案列,以及RxJava结合retrofit的封装,包括公用参数,局部参数请求头添加,缓存,https, 文件上下传,结果解析,异常处理等,还有一些 技巧 ,那么还有一个比较关键的是取消问题。</p>    <h2>Retrofit取消请求</h2>    <h2>构建API</h2>    <pre>  <code class="language-java">Call<LoginResult> call = apiService.getData("Tamic", "1234");     call.enqueue(new Callback<LoginResult>() {     @Override     public void onResponse(Call<LoginResult> call, Response<LoginResult> response) {       }       @Override     public void onFailure(Call<LoginResult> call, Throwable t) {         }     });  }</code></pre>    <h2>取消请求</h2>    <p>直接用call实例进行cancel即可</p>    <pre>  <code class="language-java">call.cancel();</code></pre>    <h2>Rxjava取消订阅</h2>    <p>遇到取消取消订阅的情况可以直接:</p>    <pre>  <code class="language-java">subscription.unsubscribe();</code></pre>    <p>避免重复:</p>    <pre>  <code class="language-java">if (!subscription.isUnsubscribed()) {      subscription.unsubscribe();  }</code></pre>    <p>如果需要在非UI线程的情况,可以直接指定线程为IO线程。</p>    <pre>  <code class="language-java">observable.unsubscribeOn(Schedulers.io());</code></pre>    <h2>Retrofit2.0+ RxJava 取消请求</h2>    <p>好了 目前很多情况是使用两者来做网络框架的,那么在两者结合情况我们是如何使用取消某个请求呢,或者避免重复请求,今天就稍微给大家介绍一下本人的处理方式</p>    <h2>构建一个接口</h2>    <p>主要管理rxJava的Subscription描述。这个东东可以理解为对一些事件所给的总Tag一样,你去办理身份证给的回执单一样,有了回执单你就可以追踪办理身份证的这个事情。</p>    <pre>  <code class="language-java">/**   * Created by Tamic on 2017-01-16.   */    public interface RxActionManager<T> {    void add(T tag, Subscription subscription);  void remove(T tag);    void cancel(T tag);    void cancelAll();  }</code></pre>    <h2>具体impl的RxApiManager</h2>    <p>主要处理真实的取消请求作用,维护rxjava的订阅池。</p>    <pre>  <code class="language-java">/**   * Created by Tamic on 2017-01-16.   */    public class RxApiManager implements RxActionManager<Object> {    private static RxApiManager sInstance = null;    private ArrayMap<Object, Subscription> maps;    public static RxApiManager get() {    if (sInstance == null) {  synchronized (RxApiManager.class) {  if (sInstance == null) {  sInstance = new RxApiManager();  }  }  }  return sInstance;  }    @TargetApi(Build.VERSION_CODES.KITKAT)  private RxApiManager() {  maps = new ArrayMap<>();  }    @TargetApi(Build.VERSION_CODES.KITKAT)  @Override  public void add(Object tag, Subscription subscription) {  maps.put(tag, subscription);  }    @TargetApi(Build.VERSION_CODES.KITKAT)  @Override  public void remove(Object tag) {  if (!maps.isEmpty()) {  maps.remove(tag);  }  }    @TargetApi(Build.VERSION_CODES.KITKAT)  public void removeAll() {  if (!maps.isEmpty()) {  maps.clear();  }  }    @TargetApi(Build.VERSION_CODES.KITKAT)  @Override public void cancel(Object tag) {  if (maps.isEmpty()) {  return;  }  if (maps.get(tag) == null) {  return;  }  if (!maps.get(tag).isUnsubscribed()) {  maps.get(tag).isUnsubscribed();  maps.remove(tag);  }  }    @TargetApi(Build.VERSION_CODES.KITKAT)  @Override public void cancelAll() {  if (maps.isEmpty()) {  return;  }  Set<Object> keys = maps.keySet();  for (Object apiKey : keys) {  cancel(apiKey);  }  }  }</code></pre>    <h2>使用姿势</h2>    <p>具体请求的subscription</p>    <p>Subscription subscription = Retrofit返回的subscription实例</p>    <p>加入rxApi管理池</p>    <pre>  <code class="language-java">RxApiManager.get().add("my", subscription);</code></pre>    <p>取消</p>    <p>RxApiManager.get().cancel(&quot;my&quot;);</p>    <p>一般我们在在activity的 onDestroy() , Fragment的 onDestroyView() 中调用</p>    <p>也可以在onPause()中取消;</p>    <pre>  <code class="language-java">@Override  protected void onPause() {      super.onPause();      RxApiManager.get().cancel("my");  }</code></pre>    <p>好了两句代码就能优雅的取消请求了,赶快试试吧!</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/d62962243c33</p>    <p> </p>