非原子缓存

时间:2018-11-01 08:47:39

标签: java android caching bitmap

正在讨论有关位图缓存的official android article

我想知道本文介绍的体系结构:

public void loadBitmap(int resId, ImageView imageView) {
    final String imageKey = String.valueOf(resId);

    final Bitmap bitmap = getBitmapFromMemCache(imageKey);
    if (bitmap != null) {
        mImageView.setImageBitmap(bitmap);
    } else {
        mImageView.setImageResource(R.drawable.image_placeholder);
        BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
        task.execute(resId);
    }
}

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    ...
    // Decode image in background.
    @Override
    protected Bitmap doInBackground(Integer... params) {
        final Bitmap bitmap = decodeSampledBitmapFromResource(
                getResources(), params[0], 100, 100));
        addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
        return bitmap;
    }
    ...
}

loadBitmap检查缓存是否存在,分离出一个异步任务,然后将该任务放入缓存中。

我想知道这是否具有风险,因为它不是原子的-您有一个组件在检查缓存,而另一个在缓存中放置东西。

  1. 将存在性检查移至doInBackground;或

  2. 以其他方式创建整个互动过程:Bitmap bitmap = getFromCacheOrDecode(key);

你们怎么看?

1 个答案:

答案 0 :(得分:1)

这没有风险,因为事实证明它是原子的。如docs中所述,LruCache是线程安全的。 UI线程将始终能够“看到” mMemoryCachedoInBackground()所做的任何先前的修改。

addBitmapToMemoryCache()中存在一些竞争状况,在此情况下,第二位后台工作人员可以在第一个后台工作人员验证mMemoryCache返回{{1之后,向getBitmapFromMemCache()添加位图}},但这没有什么实际意义。