Picasso源码完全解析(六)--请求的取消、暂停、和恢复
2017-05-17 09:14
896 查看
Picasso源码完全解析(二)--Picasso实例的创建
Picasso源码完全解析(三)--Request和Action的创建
Picasso源码完全解析(四)--Action分发和执行
Picasso源码完全解析(五)--图片的获取(BitmapHunter)
Picasso源码完全解析(六)--请求的取消、暂停、和恢复
Picasso源码完全解析(七)--
CleanupThread 取消请求
Picasso源码完全解析(六)--请求的取消、暂停、和恢复
Picasso为管理请求,提供了取消、暂停和恢复请求的方法。请求的取消
请求的取消通常是通过picasso.cancel方法执行的,最终会调用这个方法:private void cancelExistingRequest(Object target) { checkMain(); Action action = targetToAction.remove(target); if (action != null) { action.cancel(); dispatcher.dispatchCancel(action); } if (target instanceof ImageView) { ImageView targetImageView = (ImageView) target; DeferredRequestCreator deferredRequestCreator = targetToDeferredRequestCreator.remove(targetImageView); if (deferredRequestCreator != null) { deferredRequestCreator.cancel(); } } }
可以看到 是通过dispatcher.dispatchCancel(action)来执行的。在之前的基础上我们很容易明白,这是通过Dispatcher进行分发处理的。
void performCancel(Action action) { String key = action.getKey(); BitmapHunter hunter = hunterMap.get(key); if (hunter != null) { hunter.detach(action); if (hunter.cancel()) { hunterMap.remove(key); if (action.getPicasso().loggingEnabled) { log(OWNER_DISPATCHER, VERB_CANCELED, action.getRequest().logId()); } } } if (pausedTags.contains(action.getTag())) { pausedActions.remove(action.getTarget()); if (action.getPicasso().loggingEnabled) { log(OWNER_DISPATCHER, VERB_CANCELED, action.getRequest().logId(), "because paused request got canceled"); } } Action remove = failedActions.remove(action.getTarget()); if (remove != null && remove.getPicasso().loggingEnabled) { log(OWNER_DISPATCHER, VERB_CANCELED, remove.getRequest().logId(), "from replaying"); } }
没错,最终是通过
hunter.cancel()
来暂停请求的。
boolean cancel() { return action == null && (actions == null || actions.isEmpty()) && future != null && future.cancel(false); }
最终的取消是通过 future.cancel()完成的。
请求的暂停
请求的暂停是通过 picasso.pause()来完成的,具体调用流程和cancel类似,这里不再赘述,通过分析,发现最终还是通过hunter.cancel()
来暂停请求的,也就是暂停请求只不过是临时取消了这个请求。
请求的恢复
有请求的暂停也就有请求的恢复,请求的恢复是通过picass.resume()调用完成的,也是通过Dispatcher进行分的,void performResumeTag(Object tag) { // Trying to resume a tag that is not paused. if (!pausedTags.remove(tag)) { return; } List<Action> batch = null; for (Iterator<Action> i = pausedActions.values().iterator(); i.hasNext(); ) { Action action = i.next(); if (action.getTag().equals(tag)) { if (batch == null) { batch = new ArrayList<>(); } batch.add(action); i.remove(); } } if (batch != null) { mainThreadHandler.sendMessage(mainThreadHandler.obtainMessage(REQUEST_BATCH_RESUME, batch)); } }
可以看到这里是通过mainThreadHandler发送消息,我们知道mainThreadHandler是Picasso实例所在线程也就是Main线程的Handler,看看消息是如何处理的:
case REQUEST_BATCH_RESUME: @SuppressWarnings("unchecked") List<Action> batch = (List<Action>) msg.obj; //noinspection ForLoopReplaceableByForEach for (int i = 0, n = batch.size(); i < n; i++) { Action action = batch.get(i); action.picasso.resumeAction(action); } break;
再看看 action.picasso.resumeAction(action);
void resumeAction(Action action) { Bitmap bitmap = null; if (shouldReadFromMemoryCache(action.memoryPolicy)) { bitmap = quickMemoryCacheCheck(action.getKey()); } if (bitmap != null) { // Resumed action is cached, complete immediately. deliverAction(bitmap, MEMORY, action, null); if (loggingEnabled) { log(OWNER_MAIN, VERB_COMPLETED, action.request.logId(), "from " + MEMORY); } } else { // Re-submit the action to the executor. enqueueAndSubmit(action); if (loggingEnabled) { log(OWNER_MAIN, VERB_RESUMED, action.request.logId()); } } }
很明显,如果能从内存缓存中取得结果就从内存中去,否在重新提交该action。
通过上面的分析可以看到,picasso暂停和恢复请求,实际上是取消请求然后再重新提交请求,并不是真正意义上的暂停和恢复请求。
我们在实际使用过程中,往往将picasso的tag设置为统一对象,可以是所在activity的context,并在activity的生命周期中做相应的控制,或者在列表中使用的时候,为了滑动的流畅,可以根据list的滑动状态来暂停和恢复请求。
相关文章推荐
- Picasso源码完全解析(七)-- CleanupThread 取消请求
- Picasso源码完全解析(四)--Action分发和执行
- Picasso源码完全解析
- Picasso源码完全解析(一)--概述
- Picasso源码完全解析(二)--Picasso实例的创建
- Picasso源码完全解析(五)--图片的获取(BitmapHunter)
- Android 图片加载框架Picasso基本使用和源码完全解析
- Picasso源码完全解析(三)--Request和Action的创建
- Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
- Codis源码解析——proxy监听redis请求
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- Android Volley完全解析,认识,深入,自定义,源码
- Android AsyncTask完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
- Android Volley完全解析(四),带你从源码的角度理解Volley
- 源码探索系列3---四大金刚之Activity的启动过程完全解析
- Android Volley完全解析(四),带你从源码的角度理解Volley