Picasso源码阅读笔记九

223 阅读2分钟
CleanThread

Picasso在构造函数中,开启了CleanThread。CleanThread在后台运行,当内存不足时回收Action的Target并取消请求。

private static class CleanupThread extends Thread {
  private final ReferenceQueue<Object> referenceQueue; //弱引用的队列
  private final Handler handler; //主线程的Handler

  CleanupThread(ReferenceQueue<Object> referenceQueue, Handler handler) {
    this.referenceQueue = referenceQueue;
    this.handler = handler;
    setDaemon(true); //设置为守护线程
    setName(THREAD_PREFIX + "refQueue"); //设置线程名
  }

  @Override public void run() {
    Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND); //设置优先级
    // 不停查询弱引用队列中是否有可回收的引用
    while (true) {
      try {
        // 在Android 5.0以前,尽管没有了本地变量,但是remove()和obtainMessage()方法返回的结果还是保留在栈中。
        // 通过每隔1秒不停地循环来替换清除引用。
        RequestWeakReference<?> remove =
            (RequestWeakReference<?>) referenceQueue.remove(THREAD_LEAK_CLEANING_MS);
        Message message = handler.obtainMessage();
        if (remove != null) {
          // 给主线程发送REQUEST_GCED消息,让其清楚弱引用并取消请求。
          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;
      }
    }
  }

  //当Picasso被关闭时会调用该方法停止该线程。
  void shutdown() {
    interrupt();
  }
}
Stats

Stats负责记录内存缓存的状态。Stats在构造函数中启动一个HandlerThread,通过该线程接收消息,然后执行performXXX方法记录内存状态。

Stats(Cache cache) {
  this.cache = cache;
  // 这里的逻辑和Dispatcher的差不多。
  this.statsThread = new HandlerThread(STATS_THREAD_NAME, THREAD_PRIORITY_BACKGROUND);
  this.statsThread.start();
  Utils.flushStackLocalLeaks(statsThread.getLooper());
  this.handler = new StatsHandler(statsThread.getLooper(), this);
}

// 内存缓存读取成功
void performCacheHit() {
  cacheHits++;
}

// 内存缓存读取失败
void performCacheMiss() {
  cacheMisses++;
}

// 下载成功,下载数+1, 计算下载的总大小和平均下载大小
void performDownloadFinished(Long size) {
  downloadCount++;
  totalDownloadSize += size;
  averageDownloadSize = getAverage(downloadCount, totalDownloadSize);
}

// Bitmap解码,初始Bitmap数+1,计算初始Bitmap的总大小和平均Bitmap大小
void performBitmapDecoded(long size) {
  originalBitmapCount++;
  totalOriginalBitmapSize += size;
  averageOriginalBitmapSize = getAverage(originalBitmapCount, totalOriginalBitmapSize);
}

// Bitmap转化,转化Bitmap数+1,计算转化Bitmap的总大小和平均大小
void performBitmapTransformed(long size) {
  transformedBitmapCount++;
  totalTransformedBitmapSize += size;
  averageTransformedBitmapSize = getAverage(originalBitmapCount, totalTransformedBitmapSize);
}

// 返回内存状态的快照
StatsSnapshot createSnapshot() {
  return new StatsSnapshot(cache.maxSize(), cache.size(), cacheHits, cacheMisses,
      totalDownloadSize, totalOriginalBitmapSize, totalTransformedBitmapSize, averageDownloadSize,
      averageOriginalBitmapSize, averageTransformedBitmapSize, downloadCount, originalBitmapCount,
      transformedBitmapCount, System.currentTimeMillis());
}

private void processBitmap(Bitmap bitmap, int what) {
  // 不要把Bitmap发送给Handler,因为Bitmap可能在Handler处理前就被回收了。
  int bitmapSize = Utils.getBitmapBytes(bitmap);
  handler.sendMessage(handler.obtainMessage(what, bitmapSize, 0));
}