首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Picasso使用简介及分析(11)

Picasso使用简介及分析(11)

Picasso的引用清理策略

Picasso的缓存是对请求的缓存,通过WeakReference与ReferenceQueue的联合使用来缓存请求,然后
关于ReferenceQueue请看下文的详细介绍
WeakReference与ReferenceQueue联合使用构建java高速缓存

    //1.首先通过RequestWeakReference来弱化Action的引用强度
    static class RequestWeakReference<M> extends WeakReference<M> {  
      final Action action;  public RequestWeakReference(Action action, M referent, ReferenceQueue<? super M> q) {   
        super(referent, q);   
        this.action = action;  
        }
    }
     
    //2.其次通过ReferenceQueue来存放引用
    Action(Picasso picasso, T target, Request request, int memoryPolicy, int networkPolicy,  
      int errorResId, Drawable errorDrawable, String key, Object tag, boolean noFade) {  
        ...
        this.target = target == null ?
            null : new RequestWeakReference<T>(this, target, picasso.referenceQueue);  
            ...
      }
     
     
    //3.通过Picasso内部的CleanupThread来清理ReferenceQueue中的引用。
    @Override
    public void run() {  
      Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND);  
      while (true) {   
       try {      
        // Prior to Android 5.0, even when there is no local variable, the result from      
        // remove() & obtainMessage() is kept as a stack local variable.      
        // We're forcing this reference to be cleared and replaced by looping every second      
        // when there is nothing to do.      
        // This behavior has been tested and reproduced with heap dumps.   
        RequestWeakReference<?> remove = (RequestWeakReference<?>) referenceQueue.remove(THREAD_LEAK_CLEANING_MS);      
        Message message = handler.obtainMessage();      
        if (remove != null) {        
            message.what = REQUEST_GCED;        
            message.obj = remove.action;        
            handler.sendMessage(message);      
        } else {        
            message.recycle();      
          }  
        } catch (InterruptedException e) {     
           break;   
        } catch (final Exception e) {      
          handler.post(new Runnable() {        
              @Override
              public void run() {         
                  throw new RuntimeException(e);      
                }     
             });      
        break;   
         }  
        }
      }
返回列表