androidandroid-fragmentsandroid-lru-cache

Unable to reuse fragment for usage of LruCache


I'm using Google's example for caching bitmap across config changes, almost line-by-line:

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#config-changes

I am calling addBitmapToMemoryCache when a field is updated, which is way before the config change (device rotation). However, after putting debug info in findOrCreateRetainFragment:

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
    if (fragment == null) {
        fragment = new RetainFragment();
        Log.w("myapp", "instanciating new retainfragment");
        fm.beginTransaction().add(fragment, TAG).commit();
    } else {
        Log.w("myapp", "using old retainfragment");
    }
    return fragment;
}

The fragment is always newly instanciated, so I never get access to the old LruCache, despite setRetainInstance(true). Is there something wrong with Google's example? I am using the v4 support FragmentManager.

Here's the relevant portion of my onCreate:

RetainFragment retainFragment =
            RetainFragment.findOrCreateRetainFragment(getSupportFragmentManager());
mMemoryCache = retainFragment.mRetainedCache;
if (mMemoryCache == null) {
    mMemoryCache = new LruCache<String, Bitmap>(3 * 1024 * 1024) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            return bitmap.getByteCount() / 1024;
        }
    };
    retainFragment.mRetainedCache = mMemoryCache;
} else {
    backgroundsByMonth = new ArrayList<>();
    for (int i = 0; i < 12; i++) {
        BitmapDrawable bd = new BitmapDrawable(getResources(), mMemoryCache.get(Integer.toString(i)));
        backgroundsByMonth.add(bd);
    }
}

Solution

  • It turns out that my onSaveInstanceState wasn't calling the superclass onSaveInstanceState, which somehow was causing the fragment manager to lose the fragment instance. Adding

         super.onSaveInstanceState(out);
    

    fixed it.