Why do I need image cache
By default, Android only allocates 16M of memory to each application, so if too many pictures are loaded, the pictures should be cached to prevent memory overflow. The third-level cache of the picture is:
- Memory cache
- Local cache
- Network Cache
Among them, the memory cache should be loaded first, which is the fastest; the local cache should be loaded first, which is also fast; the network cache should not be loaded first, which is slow and consumes traffic.
Specific implementation of Level 3 cache
Network Cache
- Load the picture according to the url of the picture
- Cache locally and in memory
public class NetCacheUtils { private LocalCacheUtils mLocalCacheUtils; private MemoryCacheUtils mMemoryCacheUtils; public NetCacheUtils(LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) { mLocalCacheUtils = localCacheUtils; mMemoryCacheUtils = memoryCacheUtils; } /** * Download pictures from the Internet * * @param ivPic * @param url */ public void getBitmapFromNet(ImageView ivPic, String url) { new BitmapTask().execute(ivPic, url);// Start AsyncTask, // The parameters will be obtained in doInbackground } /** * Encapsulation of Handler and thread pool * * The first generic: parameter type The second generic: the generic of the update progress, the third generic is the result of onPostExecute * * */ class BitmapTask extends AsyncTask<Object, Void, Bitmap> { private ImageView ivPic; private String url; /** * The background time-consuming method is executed here, the child thread */ @Override protected Bitmap doInBackground(Object... params) { ivPic = (ImageView) params[0]; url = (String) params[1]; (url);//Bind url and imageview return downloadBitmap(url); } /** * Update progress, main thread */ @Override protected void onProgressUpdate(Void... values) { (values); } /** * After the time-consuming method is finished, execute the method, the main thread */ @Override protected void onPostExecute(Bitmap result) { if (result != null) { String bindUrl = (String) (); if ((bindUrl)) {// Make sure the image settings are given the correct imageview (result); (url, result);// Save the image locally (url, result);// Save the image in memory ("Read pictures from network cache..."); } } } } /** * Download the picture * * @param url * @return */ private Bitmap downloadBitmap(String url) { HttpURLConnection conn = null; try { conn = (HttpURLConnection) new URL(url).openConnection(); (5000); (5000); ("GET"); (); int responseCode = (); if (responseCode == 200) { InputStream inputStream = (); //Picture compression processing option = new (); = 2;//The width and height are compressed to half of the original. This parameter needs to be determined based on the size of the picture to be displayed. = .RGB_565;//Set picture format Bitmap bitmap = (inputStream, null, option); return bitmap; } } catch (Exception e) { (); } finally { (); } return null; } }
Local cache
Two methods: set local cache and get local cache
public class LocalCacheUtils { public static final String CACHE_PATH = Environment .getExternalStorageDirectory().getAbsolutePath() + "/local_cache"; /** * Read pictures from local sdcard */ public Bitmap getBitmapFromLocal(String url) { try { String fileName = (url); File file = new File(CACHE_PATH, fileName); if (()) { Bitmap bitmap = (new FileInputStream( file)); return bitmap; } } catch (Exception e) { (); } return null; } /** * Write pictures to SDcard * * @param url * @param bitmap */ public void setBitmapToLocal(String url, Bitmap bitmap) { try { String fileName = (url); File file = new File(CACHE_PATH, fileName); File parentFile = (); if (!()) {// If the folder does not exist, create a folder (); } // Save the image locally (, 100, new FileOutputStream(file)); } catch (Exception e) { (); } } }
Memory cache
Two methods: set the memory cache and obtain the memory cache
question:
If you use HashMap to store images, it will cause memory overflow when there are more and more pictures, because it is a strong reference, and Java's garbage collector will not recycle it.
If it is changed to a soft reference SoftReference (the garbage collector will consider recycling when the memory is insufficient), there is still a problem: in android 2.3+, the system will prioritize the SoftReference object in advance, even if the memory is sufficient.
Solution: LruCache can be used to solve the above-mentioned problem of not recycling or early recycling. least recently use The algorithm that will control the memory to a certain size and will automatically recycle it when it exceeds the maximum value. The developer will set this maximum value by himself.
public class MemoryCacheUtils { // private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new // HashMap<String, SoftReference<Bitmap>>(); private LruCache<String, Bitmap> mMemoryCache; public MemoryCacheUtils() { long maxMemory = ().maxMemory() / 8;// The default emulator is 16M mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) { @Override protected int sizeOf(String key, Bitmap value) { int byteCount = () * ();// Get the memory size of the image return byteCount; } }; } /** * Read from memory * * @param url */ public Bitmap getBitmapFromMemory(String url) { // SoftReference<Bitmap> softReference = (url); // if (softReference != null) { // Bitmap bitmap = (); // return bitmap; // } return (url); } /** * Write memory * * @param url * @param bitmap */ public void setBitmapToMemory(String url, Bitmap bitmap) { // SoftReference<Bitmap> softReference = new // SoftReference<Bitmap>(bitmap); // (url, softReference); (url, bitmap); } }
Image compression
//Image compression processing (compression is performed when obtaining pictures from the network) option = new (); = 2;//The width and height are compressed to half of the original. This parameter needs to be determined based on the size of the picture to be displayed. = .RGB_565;//Set picture format Bitmap bitmap = (inputStream, null, option);
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.