Merge "Evict thumbnail caches and delay dismissing spinner on refresh finish."
This commit is contained in:
committed by
Android (Google) Code Review
commit
eadd9ca5ac
@@ -111,6 +111,13 @@ public class ThumbnailCache {
|
||||
return Result.obtainMiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a thumbnail for the given uri and size in to the cache.
|
||||
* @param uri the uri of the thumbnail
|
||||
* @param size the size of the thumbnail
|
||||
* @param thumbnail the thumbnail to put in cache
|
||||
* @param lastModified last modified value of the thumbnail to track its validity
|
||||
*/
|
||||
public void putThumbnail(Uri uri, Point size, Bitmap thumbnail, long lastModified) {
|
||||
Pair<Uri, Point> cacheKey = Pair.create(uri, size);
|
||||
|
||||
@@ -130,14 +137,33 @@ public class ThumbnailCache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all thumbnail cache associated to the given uri.
|
||||
* @param uri the uri which thumbnail cache to remove
|
||||
*/
|
||||
public void removeUri(Uri uri) {
|
||||
TreeMap<Point, Pair<Uri, Point>> sizeMap;
|
||||
synchronized (mSizeIndex) {
|
||||
sizeMap = mSizeIndex.get(uri);
|
||||
}
|
||||
|
||||
if (sizeMap != null) {
|
||||
// Create an array to hold all values to avoid ConcurrentModificationException because
|
||||
// removeKey() will be called by LruCache but we can't modify the map while we're
|
||||
// iterating over the collection of values.
|
||||
for (Pair<Uri, Point> index : sizeMap.values().toArray(new Pair[0])) {
|
||||
mCache.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeKey(Uri uri, Point size) {
|
||||
TreeMap<Point, Pair<Uri, Point>> sizeMap;
|
||||
synchronized (mSizeIndex) {
|
||||
sizeMap = mSizeIndex.get(uri);
|
||||
}
|
||||
|
||||
// LruCache tells us to remove a key, which should exist, so sizeMap can't be null.
|
||||
assert (sizeMap != null);
|
||||
assert(sizeMap != null);
|
||||
synchronized (sizeMap) {
|
||||
sizeMap.remove(size);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.DocumentsContract.Document;
|
||||
@@ -92,6 +93,7 @@ import com.android.documentsui.Shared;
|
||||
import com.android.documentsui.Snackbars;
|
||||
import com.android.documentsui.State;
|
||||
import com.android.documentsui.State.ViewMode;
|
||||
import com.android.documentsui.ThumbnailCache;
|
||||
import com.android.documentsui.clipping.DocumentClipper;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
|
||||
@@ -140,6 +142,9 @@ public class DirectoryFragment extends Fragment
|
||||
private static final String TAG = "DirectoryFragment";
|
||||
private static final int LOADER_ID = 42;
|
||||
|
||||
private static final int CACHE_EVICT_LIMIT = 100;
|
||||
private static final int REFRESH_SPINNER_DISMISS_DELAY = 500;
|
||||
|
||||
private Model mModel;
|
||||
private MultiSelectManager mSelectionMgr;
|
||||
private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
|
||||
@@ -1610,6 +1615,17 @@ public class DirectoryFragment extends Fragment
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
// Remove thumbnail cache. We do this not because we're worried about stale thumbnails as it
|
||||
// should be covered by last modified value we store in thumbnail cache, but rather to give
|
||||
// the user a greater sense that contents are being reloaded.
|
||||
ThumbnailCache cache = DocumentsApplication.getThumbnailCache(getContext());
|
||||
String[] ids = mModel.getModelIds();
|
||||
int numOfEvicts = Math.min(ids.length, CACHE_EVICT_LIMIT);
|
||||
for (int i = 0; i < numOfEvicts; ++i) {
|
||||
cache.removeUri(mModel.getItemUri(ids[i]));
|
||||
}
|
||||
|
||||
// Trigger loading
|
||||
getLoaderManager().restartLoader(LOADER_ID, null, this);
|
||||
}
|
||||
|
||||
@@ -1679,7 +1695,11 @@ public class DirectoryFragment extends Fragment
|
||||
|
||||
mTuner.onModelLoaded(mModel, mType, mSearchMode);
|
||||
|
||||
mRefreshLayout.setRefreshing(false);
|
||||
if (mRefreshLayout.isRefreshing()) {
|
||||
new Handler().postDelayed(
|
||||
() -> mRefreshLayout.setRefreshing(false),
|
||||
REFRESH_SPINNER_DISMISS_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -176,6 +176,18 @@ public class ThumbnailCacheTest {
|
||||
assertSame(SMALL_BITMAP, result.getThumbnail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveUri() {
|
||||
mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
|
||||
mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED);
|
||||
mCache.putThumbnail(URI_1, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
|
||||
|
||||
mCache.removeUri(URI_0);
|
||||
|
||||
assertMiss(mCache.getThumbnail(URI_0, MID_SIZE));
|
||||
assertHitExact(mCache.getThumbnail(URI_1, MID_SIZE));
|
||||
}
|
||||
|
||||
private static void assertMiss(Result result) {
|
||||
assertEquals(Result.CACHE_MISS, result.getStatus());
|
||||
assertFalse(result.isExactHit());
|
||||
|
||||
Reference in New Issue
Block a user