About three-level caching in Android,

Source: Internet
Author: User

About three-level caching in Android,

Third-level cache is proposed to improve user experience. When we first open the application to retrieve images, we first download images from the network, and then store them in the memory cache and disk cache. When we need to use this image again, you do not need to repeat the network to download the image. You can directly find the image from the memory cache and disk cache. Because the memory cache speed is fast, we should first search for the image in the memory cache, if it is found, it will be used. If it is not found (the memory cache size is limited), we will find it in the disk cache. As long as we properly coordinate the use of these three layers of cache, we can improve application performance. Three-level cache refers to memory cache, local cache, and network cache. Their respective characteristics are that the memory cache speed is fast, the first is read, the second is the local cache speed, the second is the memory speed, the local is read, the network cache speed is the slowest, and the local is not, only access to the network. For Network cache, it is easier to get resources directly from the network. The local cache can exist in the SD card, and the memory cache generally exists in arrays or collections. Note that the lifecycle of an array and a set depends on its existing activity. Therefore, when the program exits, resources in the array and set are usually released. It is necessary to introduce several concepts before learning the working principles of Level 3 caching.

Instances and objects:
An object is an instance of a class. The process of creating an object is also called class instantiation. Objects are created using classes as templates. In this way, at the bottom of Android, a heap will be used to store object instances and stacks to store class objects. A reference refers to the fact that some objects require other object instances for instantiation. For example, if an ImageView is instantiated, a Context object is required, indicating that ImageView holds a reference to Context for the Context (ImageView holds a reference to Context ).

Garbage collection mechanism (GC ):
Identifies the available memory space of the VM, that is, the objects in the heap space. If the object is being referenced, it is called a surviving object. If the object is no longer referenced, It is a junk object, the space occupied by it can be recycled for redistribution. In more detail, when a programmer creates an object, GC starts to monitor the address, size, and usage of the object. Generally, GC records and manages all objects in the heap by Directed Graphs. In this way, it determines which objects are "reachable" and which objects are "inaccessible ". When the object is inaccessible, that is, when the object is no longer referenced, it will be reclaimed. This mechanism marks the memory in the virtual machine, and determines which memory needs to be recycled. According to a certain recovery policy, the memory is automatically recycled and never stops (Nerver Stop) to ensure the memory space in the virtual machine, prevent Memory leakage and overflow problems.

Memory leakage:
When an instance is no longer needed, but the object is still referenced, this situation is called Memory leakage (Memory Leak ). The android Virtual Machine allocates a certain amount of memory space for each application. When the memory leakage reaches a certain level, it will cause memory overflow.

Memory Reference:
Memory reference levels include strong reference, soft reference, weak reference, and virtual reference. Strong reference is the default reference method, and will not be recycled even if the memory overflows. Soft reference (softReference), when the memory is not enough, it will be considered to be recycled. When WeakReference memory is insufficient, it is more likely to be recycled. When the memory of the PhantomReference is insufficient, reclaim is the highest priority! Generally, a reference is a strong reference. For example, a reference is used to create a reference in a member variable. For GC, the intensity of SoftReference is significantly lower than that of SrongReference. SoftReference-modified references tell GC: I am a soft reference. When the memory is insufficient, the memory I point to can be released for you. SoftReference is generally considered for variables that occupy a large amount of memory resources and are not necessary; or for some cached variables that occupy a large amount of memory resources. For GC, the intensity of WeakReference is significantly lower than that of SoftReference. WeakReference indicates GC: I am a weak reference. I have nothing to say about your requirements. The memory I direct to can be released for you. Virtual references are not the same as the various references mentioned above. They are mainly used to track when an object is recycled by GC. It is also useful in android: FileCleaner. java. These reference methods to avoid memory overflow do not play a major role in Android 2.3 + versions, because the Garbage Collector frequently recycles non-strongly referenced objects. Android officially recommends using LRUCache. Therefore, when we use soft references for memory cache, we will find that the resources in the memory will be frequently recycled by the system. In the end, data is read locally.

In this way, we can better understand the three-level cache. First, read data in the memory. The least recently referenced algorithm (lrucache) is used to read data in the memory ). The Lrucache algorithm must be new LruCache <String, Bitmap> () to pass in the maximum memory allocated to the software, and rewrite the sizeof () method to calculate the size of each image. In this way, you can directly call the put () and get () Methods of LruCache. If no data is found in the memory, find the storage file in the SD card. Use the compress () method of Bitmap to write data to the folder, read data through the decodeStream () of BitmapFactory In the Bitmap factory, and pass in the options parameter for the decodeStream () method to narrow down the image. Finally, if no data is obtained locally, it is obtained from the network. Asynchronous tasks can be used to obtain data from the Network (time-consuming operations cannot be executed in the main thread ). The onPostExecute () method and doInBackground () method must be rewritten for asynchronous tasks. Access the network in the doInBackground () method. Httpurlconnection is used here to obtain the input stream through the connection. The bitmap factory is used to convert it into a bitmap and return it. The onPostExecute () method is executed after the doInBackground () method is executed. The number of input parameters returned by the doInBackground () method.

The following is the code implementation. This is the method for calling the tool class:

import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.ImageView;import com.example.huang.demo.utils.CacheUtils;public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        getBitmap();    }    private void getBitmap() {        iv = (ImageView) findViewById(R.id.iv);        CacheUtils utils = new CacheUtils();        utils.diaplay(iv,"http://192.168.23.48:8080/test.jpg");        }}

The layout file is not written into an imageview. The cache tool class is as follows:

Import android. graphics. bitmap; import android. util. log; import android. widget. imageView;/*** Created by huang on 2016/12/3. */public class CacheUtils {private static final String TAG = "CacheUtils"; private MemoryCacheUtils extensions; private LocalCacheUtils extensions; private NetCacheUtils extensions; public CacheUtils () {Signature = new MemoryCacheUtils (); mLocalCache Utils = new LocalCacheUtils (); mNetCacheUtils = new NetCacheUtils (mMemoryCacheUtils, mLocalCacheUtils);} public void diaplay (ImageView imageView, String url) {// The memory cache lifecycle is the same as that of the caller Bitmap bitmap = mMemoryCacheUtils. getBitmapToMemory (url); if (bitmap! = Null) {imageView. setImageBitmap (bitmap); Log. I (TAG, "diaplay: 221111111111"); return;} // The local cache bitmap = LocalCacheUtils. getBitmapToLoacl (url); if (bitmap! = Null) {Log. I (TAG, "diaplay: 1111111"); imageView. setImageBitmap (bitmap); mMemoryCacheUtils. putBitmapToMemory (bitmap, url); return ;}// network cache mNetCacheUtils. getBitmapFromNet (imageView, url );}}

Memory Cache Tool

import android.graphics.Bitmap;import android.util.Log;import android.util.LruCache;import static android.content.ContentValues.TAG;/** * Created by huang on 2016/12/3. */public class MemoryCacheUtils {    private LruCache<String, Bitmap> mMemoryCache;    public MemoryCacheUtils() {        int maxmemory = (int) Runtime.getRuntime().maxMemory();        Log.i(TAG, "MemoryCacheUtils: " + maxmemory);        mMemoryCache = new LruCache<String, Bitmap>(maxmemory / 8) {            @Override            protected int sizeOf(String key, Bitmap value) {                return value.getRowBytes() * value.getHeight();            }        };    }    public void putBitmapToMemory(Bitmap bitmap, String url) {        Log.i(TAG, "putBitmapToMemory: ");        mMemoryCache.put(url, bitmap);    }    public Bitmap getBitmapToMemory(String url) {        Log.i(TAG, "getBitmapToMemory: ");        Bitmap bitmap = mMemoryCache.get(url);        return bitmap;    }}

 

Tools for local cache (SD card:

import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Environment;import android.util.Log;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import static android.content.ContentValues.TAG;/** * Created by huang on 2016/12/3. */public class LocalCacheUtils {    public static void putBitmapToLoacl(Bitmap bitmap, String url) {        String encode = Md5Utils.encode(url);        File file = new File(Environment.getExternalStorageDirectory(), encode);        Log.i(TAG, "putBitmapToLoacl: " + file.toString());        File parent = file.getParentFile();        if (!parent.exists()) {            parent.mkdirs();        }        try {            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(file));        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }    public static Bitmap getBitmapToLoacl(String url) {        String encode = Md5Utils.encode(url);        File file = new File(Environment.getExternalStorageDirectory(), encode);        if (file.exists()) {            BitmapFactory.Options opts = new BitmapFactory.Options();            opts.inSampleSize = 3;            try {                Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file), null, opts);                return bitmap;            } catch (FileNotFoundException e) {                e.printStackTrace();                return null;            }        }        return null;    }}

Network cache tool class:

import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;/** * Created by huang on 2016/12/3. */public class NetCacheUtils {    private MemoryCacheUtils mMemoryCacheUtils;    private LocalCacheUtils mLocalCacheUtils;    public NetCacheUtils(MemoryCacheUtils mMemoryCacheUtils, LocalCacheUtils mLocalCacheUtils) {        this.mLocalCacheUtils = mLocalCacheUtils;        this.mMemoryCacheUtils = mMemoryCacheUtils;    }    public void getBitmapFromNet(ImageView imageView, String url) {        imageView.setTag(url);        Bitmaptask task = new Bitmaptask();        task.execute(imageView, url);    }    class Bitmaptask extends AsyncTask<Object, Void, Bitmap> {        private HttpURLConnection urlConnection;        private ImageView imageView;        private String url;        @Override        protected void onPostExecute(Bitmap bitmap) {            if (bitmap != null) {                if (url.equals(imageView.getTag())) {                    imageView.setImageBitmap(bitmap);                    System.out.print("onPostExecute");                    mLocalCacheUtils.putBitmapToLoacl(bitmap, url);                    mMemoryCacheUtils.putBitmapToMemory(bitmap, url);                }            }        }        @Override        protected Bitmap doInBackground(Object[] params) {            imageView = (ImageView) params[0];            url = (String) params[1];            Bitmap bitmap = downloadFromNet(url);            return bitmap;        }        private Bitmap downloadFromNet(String url) {            try {                urlConnection = (HttpURLConnection) new URL(url).openConnection();                urlConnection.setConnectTimeout(5000);                urlConnection.setRequestMethod("GET");                int responseCode = urlConnection.getResponseCode();                if (responseCode == 200) {                    InputStream inputStream = urlConnection.getInputStream();                    BitmapFactory.Options opts = new BitmapFactory.Options();                    opts.inSampleSize = 2;                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, opts);                    return bitmap;                }            } catch (IOException e) {                e.printStackTrace();                return null;            } finally {                urlConnection.disconnect();            }            return null;        }    }}

The MD5Utils tool class used in the local cache:

import java.security.MessageDigest;/** * Created by huang on 2016/12/3. */public class Md5Utils {    public static String encode(String pwd) {        try {            MessageDigest digest = MessageDigest.getInstance("md5");            byte[] bs = digest.digest(pwd.getBytes());            StringBuilder sb = new StringBuilder();            for (byte b : bs) {                int number = b & 0xff;                String str = Integer.toHexString(number);                if (str.length() == 1) {                    sb.append("0");                }                sb.append(number);            }            return sb.toString();        } catch (Exception e) {            e.printStackTrace();            return null;        }    }}

Do not forget to add permissions:

    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.