privateLruCachemMemoryCache;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){...// Get memory class of this device, exceeding this amount will throw an // OutOfMemory exception. finalintmemClass=((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();// Use 1/8th of the available memory for this memory cache. finalintcacheSize=1024*1024*memClass/8;mMemoryCache=newLruCache(cacheSize){@OverrideprotectedintsizeOf(Stringkey,Bitmapbitmap){// The cache size will be measured in bytes rather than number of items. returnbitmap.getByteCount();}};...}publicvoidaddBitmapToMemoryCache(Stringkey,Bitmapbitmap){if(getBitmapFromMemCache(key)==null){mMemoryCache.put(key,bitmap);}}publicBitmapgetBitmapFromMemCache(Stringkey){returnmMemoryCache.get(key);}
privateDiskLruCachemDiskCache;privatestaticfinalintDISK_CACHE_SIZE=1024*1024*10;// 10MB privatestaticfinalStringDISK_CACHE_SUBDIR="thumbnails";@OverrideprotectedvoidonCreate(BundlesavedInstanceState){...// Initialize memory cache ...FilecacheDir=getCacheDir(this,DISK_CACHE_SUBDIR);mDiskCache=DiskLruCache.openCache(this,cacheDir,DISK_CACHE_SIZE);...}classBitmapWorkerTaskextendsAsyncTask{...// Decode image in background. @OverrideprotectedBitmapdoInBackground(Integer...params){finalStringimageKey=String.valueOf(params[0]);// Check disk cache in background thread Bitmapbitmap=getBitmapFromDiskCache(imageKey);if(bitmap==null){// Not found in disk cache // Process as normal finalBitmapbitmap=decodeSampledBitmapFromResource(getResources(),params[0],100,100));}// Add final bitmap to caches addBitmapToCache(String.valueOf(imageKey,bitmap);returnbitmap;}...}publicvoidaddBitmapToCache(Stringkey,Bitmapbitmap){// Add to memory cache as before if(getBitmapFromMemCache(key)==null){mMemoryCache.put(key,bitmap);}// Also add to disk cache if(!mDiskCache.containsKey(key)){mDiskCache.put(key,bitmap);}}publicBitmapgetBitmapFromDiskCache(Stringkey){returnmDiskCache.get(key);}// Creates a unique subdirectory of the designated app cache directory. Tries to use external // but if not mounted, falls back on internal storage. publicstaticFilegetCacheDir(Contextcontext,StringuniqueName){// Check if media is mounted or storage is built-in, if so, try and use external cache dir // otherwise use internal cache dir finalStringcachePath=Environment.getExternalStorageState()==Environment.MEDIA_MOUNTED||!Environment.isExternalStorageRemovable()?context.getExternalCacheDir().getPath():context.getCacheDir().getPath();returnnewFile(cachePath+File.separator+uniqueName);}
幸运的是,在前面介绍Use a Memory Cache的部分,你已经知道如何建立一个内存缓存。这个缓存可以通过使用一个Fragment去调用 setRetainInstance(true)) 传递到新的Activity中。在这个activity被recreate之后, 这个保留的 Fragment 会被重新附着上。这样你就可以访问Cache对象,从中获取到图片信息并快速的重新添加到ImageView对象中。
privateLruCachemMemoryCache;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){...RetainFragmentmRetainFragment=RetainFragment.findOrCreateRetainFragment(getFragmentManager());mMemoryCache=RetainFragment.mRetainedCache;if(mMemoryCache==null){mMemoryCache=newLruCache(cacheSize){...// Initialize cache here as usual }mRetainFragment.mRetainedCache=mMemoryCache;}...}classRetainFragmentextendsFragment{privatestaticfinalStringTAG="RetainFragment";publicLruCachemRetainedCache;publicRetainFragment(){}publicstaticRetainFragmentfindOrCreateRetainFragment(FragmentManagerfm){RetainFragmentfragment=(RetainFragment)fm.findFragmentByTag(TAG);if(fragment==null){fragment=newRetainFragment();}returnfragment;}@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setRetainInstance(true);}}