*pure LRU - caching without use of picasso library
In ThumbnailDownloader I added:
private LruCache<String, Bitmap> mMemoryCache;
Updated constructor
public ThumbnailDownloader(Handler responseHandler) {
super(TAG);
mResponseHandler = responseHandler;
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
// The cache size will be measured in kilobytes rather than
// number of items.
return value.getByteCount() / 1024;
}
};
}
added:
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemoryCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemoryCache(String key) {
return mMemoryCache.get(key);
}
after that upd onLooperPrepared():
@Override
protected void onLooperPrepared() {
mRequestHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MESSAGE_DOWNLOAD) {
T target = (T) msg.obj;
Log.i(TAG, "Got a request for URL: " + mRequestMap.get(target));
handleRequest(target);
} else if (msg.what == MESSAGE_CACHE) {
T target = (T) msg.obj;
Log.i(TAG, "Got a request for cache URL: " + mRequestMap.get(target));
handleCacheRequest(target);
}
}
};
}
added:
public void queueThumbnailCache(String url) {
Log.i(TAG, "Got a URL for cache: " + url);
mRequestHandler.obtainMessage(MESSAGE_CACHE, url).sendToTarget();
}
and added:(I removed from handleRequest “addBitmapToMemoryCache(url, bitmap);”)
private void handleCacheRequest(final T target) {
final String url = (String)target;
if (url == null) {
return;
}
Log.d(TAG, "handleCacheRequest: " + url);
final Bitmap bitmapFromMemoryCache = getBitmapFromMemoryCache(url);
try {
if (bitmapFromMemoryCache != null) {
return;
} else {
byte[] bitmapBytes;
bitmapBytes = new FlickrFetchr().getUrlBytes(url);
final Bitmap bitmap = BitmapFactory
.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
mResponseHandler.post(() -> {
if (target != url || mHasQuit) {
return;
}
addBitmapToMemoryCache(url, bitmap);
});
}
} catch (IOException e) {
Log.e(TAG, "Error downloading image", e);
}
}
In PhotoGalleryFragment:
Added:
private int mLastPosition;
private int mFirstPosition;
in onCreateView(…) we need smth like:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_photo_gallery, container, false);
mPhotoRecyclerView = v.findViewById(R.id.photo_recycler_view);
mPhotoRecyclerView.getViewTreeObserver().
addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
float columnWidthInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
140, getActivity().getResources().getDisplayMetrics());
int width = mPhotoRecyclerView.getWidth();
int columnNumber = Math.round(width / columnWidthInPixels);
mGridLayoutManager = new GridLayoutManager(getActivity(), columnNumber);
mPhotoRecyclerView.setLayoutManager(mGridLayoutManager);
mPhotoRecyclerView.scrollToPosition(mFirstPosition);
mPhotoRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mPhotoRecyclerView.setOnScrollChangeListener((v1, scrollX, scrollY, oldScrollX, oldScrollY) -> {
mFirstPosition = mGridLayoutManager.findFirstVisibleItemPosition();
mLastPosition = mGridLayoutManager.findLastVisibleItemPosition();
if (!mUserScrolled) {
if (mLastPosition == mItems.size() - 1) {
mUserScrolled = true;
Toast.makeText(getActivity(), "Bottom" + mLastPosition, Toast.LENGTH_SHORT).show();
new FetchItemsTask().execute();
}
//caching
int top = (mFirstPosition > 10) ? mFirstPosition - 10 : 0;
int bottom = mLastPosition > mItems.size() - 11 ?
mItems.size() : mLastPosition + 10;
for (int i = top; i < bottom; i++) {
mThumbnailDownloader.queueThumbnailCache(mItems.get(i).getUrl());
}
//caching
}
});
}
setupAdapter();
return v;
}