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("my");</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>