Android uses caching to implement file download and asynchronous request picture plus level three cache _android

Source: Internet
Author: User
Tags garbage collection int size md5 parent directory static class

First of all introduce Android using caching mechanism to implement file download

When downloading files or browsing files online, or in order to ensure the correctness of file downloads, you need to use the caching mechanism, often using softreference to implement.

The SoftReference feature is that an instance of it holds soft references to a Java object that does not prevent garbage collection threads from reclaiming the Java object. That is, once SoftReference has saved a soft reference to a Java object, the Get () method provided by the SoftReference class returns a strong reference to the Java object before the garbage thread reclaims the Java object. Also, once the garbage thread reclaims the Java object, the Get () method returns NULL. A soft reference can be used in conjunction with a reference queue (Referencequeue), and the Java Virtual machine will add the soft reference to the reference queue associated with it if the object referenced by the soft reference is reclaimed by the garbage collector.

The general caching strategy is:

First-level memory cache, level two file cache (database also counted as file cache), level three network data

One, the network downloads the cache policy

Basic strategies for downloading files (pictures, audio, video) on your network:

1. Do not download directly to the target file, you should use the temp file for transit to ensure the correctness and integrity of the document, the process is as follows:

A to generate a unique local destination file name with network destination filename A (B)

b Generate a unique local temporary filename with local target filename B T

c) Download files to T

d) Download completed, verify the correctness and completeness of the file T

e if incorrect or incomplete, delete the file T and return False

f) After the checksum is finished, rename or copy the file T to the B file

G Final cleanup site, delete temp file T, after success, return true

2. Make every effort to provide correctness and integrity of the document calibration:

A) Correctness: for example, Md5/hash Code alignment, file format comparison.
B Integrity: such as the file size is consistent, picture data is correct (picture file header provides relevant information)

3. Consider whether two more processing is required for downloading to a local file, thinking about the following:

A) For example, the size of the network source image is 800*600, and we need to be the size of the thumbnail as 160*145, so consider the download after the file to crop, and then save, for the source file is deleted directly.

Second, file caching strategy:

1. Need a unique cache file corresponding I/O key, can generally use hashcode.

2. If the same file, at different times, you can consider, first clear the local cache, and then download the new cache to the local.

3. The same file can be added with a timestamp, then the unique hashcode is generated.

4. The following comprehensive considerations may be required to generate file mitigation:

A sdcard there is no space (this requirement exists, but few people will consider that once it happens, it must be crash).

b the Cache cleanup policy. Daily, weekly regular cleaning? When a threshold is reached, it is cleaned automatically? (If there is no clean-up strategy, the garbage data have been as a treasure one phase of storage,

is a very SB's).

c) Caching the data that is really needed. Do not feel the external memory is unlimited, so you can save anything, you know, many are complex, complex is chaotic. Once a colleague, save hundreds of MB of user data per day (all user's gender, age, contact information, etc.), and PM needs only a daily number of active data reports, and then finally cached daily user Analysis report data can (only 10 KB).

D) To encrypt the cached file. The simplest is to remove the file extension, which is also encrypted, of course, you can encrypt the server-side file, and then decrypt in memory. This depends on the requirements of the project, my experience is not enough, the general is to change the name of the extension and so on.

Here's an introduction to Android asynchronous request picture plus level three cache

The use of Xutils framework is very convenient, but today to use code to achieve Bitmaputils function, very simple,

1 Asynctask Request a picture

### #AsyncTask
# # # # # # # # # # # # # # #AsyncTask是线程池 +handler encapsulation The first generic: parameter type type of the argument (consistent with Doinbackground) the second generic:
# # # #更新进度的参数类型 (consistent with onprogressupdate) the third generic: Returns the parameter type of the result (consistent with OnPostExecute,
# #和doInBackground返回类型一致)

See Asynctask Source:

Public abstract class Asynctask<params, Progress, result> {
private static final String Log_tag = "Asynctask"; 
   private static final int core_pool_size = 5;
private static final int maximum_pool_size = 128;
private static final int keep_alive = 1;
private static final Threadfactory sthreadfactory = new Threadfactory () {
private final atomicinteger mcount = new Ato Micinteger (1);
Public thread Newthread (Runnable r) {return
new Thread (R, "Asynctask #" + mcount.getandincrement ());
}

Core thread 5 Max thread 128 This is the Asynctask thread pool and then sends the message through Handler, which internally instantiates a static custom class Internalhandler, which inherits from Handler, and in this custom class is bound with a name called The Asynctaskresult object, each time the child thread needs to notify the main thread, calls Sendtotarget to send the message to handler itself. Then in handler's Handlemessage asynctaskresult depending on the type of message (for example, message_post_progress updates the progress bar, Message_post_cancel To cancel a task and do different things, it is worth mentioning that these operations are performed on the UI thread, meaning that the handler object is automatically invoked on the main thread once the child thread is required to interact with the UI thread.

private static final Internalhandler Shandler = new Internalhandler ();
Mfuture = new Futuretask<result> (mworker) {@Override protected void more ... do () {message message;
result result = NULL;
try {result = Get ();} catch (Interruptedexception e) {ANDROID.UTIL.LOG.W (Log_tag, E);} catch (Executionexception e) {
throw new RuntimeException ("An error occured while executing doinbackground ()", E.getcause ()); catch (cancellationexception e) {message = Shandler.obtainmessage (Message_post_cancel, New Asynctaskresult<result
> (Asynctask.this, (result[)) (null));
Message.sendtotarget ();
Return
catch (Throwable t) {throw new RuntimeException ("An error occured while executing" + "doinbackground ()", t);}
Message = Shandler.obtainmessage (Message_post_result, New asynctaskresult<result> (asynctask.this, result));
Message.sendtotarget ();
}
}; private static class Internalhandler extends Handler {@SuppressWarnings ({"Unchecked", "Rawuseofparameterizedtype"}) @ Override PublIC void More ... handlemessage (message msg) {Asynctaskresult result = (asynctaskresult) msg.obj; switch (msg.what) {case
Message_post_result://There is only one result Result.mTask.finish (result.mdata[0]);
Break
Case MESSAGE_POST_PROGRESS:result.mTask.onProgressUpdate (Result.mdata);
Break
Case MESSAGE_POST_CANCEL:result.mTask.onCancelled ();
Break }
}
}

Look at the first step of the code we first request a picture and parse the note written in detail.

Netcacheutils.java

Import Java.io.InputStream;
Import java.net.HttpURLConnection;
Import Java.net.URL;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import Android.os.AsyncTask;
Import Android.widget.ImageView; /** * Network Cache * * @author Ace * @date 2016-02-18/public class Netcacheutils {private Localcacheutils mlocalutils; privat
e memorycacheutils mmemoryutils; Public Netcacheutils (Localcacheutils localutils, memorycacheutils memoryutils) {mlocalutils = localUtils; mMemoryUtils
= Memoryutils; public void Getbitmapfromnet (ImageView imageview, String URL) {bitmaptask task = new Bitmaptask (); Task.execute (Imagevi
ew, URL); /** * Asynctask is the wrapper of the thread pool +handler the first generic: parameter type type of the argument (and Doinbackground consistent) second generic: * Update progress parameter type (and onprogressupdate consistent) third generic: Returns the parameter type of the result (consistent with OnPostExecute, * and Doinbackground return type) * * Class Bitmaptask extends Asynctask<object, Integer, Bitmap > {private ImageView mimageview; private String URL;//main thread run, preload @Override protected void OnPreExecute () {SUPER.ONP ReexeCute (); //Child threads run, asynchronous load logic is handled in this method @Override protected Bitmap doinbackground (Object ... params) {Mimageview = (ImageView) params[0]
;
url = (String) params[1];
Mimageview.settag (URL);//bind ImageView and URL together//publishprogress (values)//Notify progress//Download picture return download (URL); }//Main thread run, update progress @Override protected void onprogressupdate (Integer ... values) {super.onprogressupdate (values);}//Main thread run , update the main interface @Override protected void OnPostExecute (Bitmap result) {if (result!= null) {//To determine if the current picture is the ImageView picture to prevent LISTVI
Image confusion caused by EW reuse occurs with string Bindurl = (string) mimageview.gettag ();
if (bindurl.equals (URL)) {//to ImageView set the picture Mimageview.setimagebitmap (result);//Save pictures locally
Mlocalutils.setbitmaptolocal (result, URL);
Save the picture in memory mmemoryutils.setbitmaptomemory (URL, result); /** * Download picture * * @param url/public Bitmap download (String URL) {HttpURLConnection conn = null; try {conn = (Ht
tpurlconnection) (new URL (URL). OpenConnection ());
Conn.setconnecttimeout (5000);
Conn.setreadtimeout (5000); Conn. Setrequestmethod ("get");
Conn.connect ();
int responsecode = Conn.getresponsecode (); if (Responsecode =) {InputStream in = Conn.getinputstream ();///Convert to Bitmap object Bitmap Bitmap = Bitmapfactory.decodest
Ream (in);
return bitmap;
} catch (Exception e) {e.printstacktrace ();} finally {if (conn!= null) {Conn.disconnect ();}} return null; }
}

Memorycacheutils.java used LRUCache Simple I translated the document:

* A cache that holds strong references to a limited number of values. Each time * A value was accessed, it is moved to the head of a queue. When a value was * added to a full cache, the value at the "end of" \ Evicted and may * become eligible for GAR 
Bage collection.
* Cache saves a strong reference to limit the amount of content, and whenever item is accessed, the item is moved to the head of the queue. 
* When a new item is added when the cache is full, the item at the end of the queue is reclaimed. 
* <p>if your cached values hold resources this need to be explicitly released, * override {@link #entryRemoved}. * If a value of your cache needs to be explicitly released, rewrite entryremoved () * <p>by default, the cache size is measured in the number of entries. Override * {@link #sizeOf} to size of the cache in different units.
 For example, this cache * was limited to 4MiB of bitmaps: The default cache size is the number of item measurements, and the rewrite sizeof calculates the size of the different item. {@code * int cacheSize = 4 * 1024 * 1024;//4MiB * lrucache<string, bitmap> bitmapcache = new Lrucache<strin G, bitmap> (cacheSize) {* protected int sizeOf (String key, Bitmap value) {* Return value.geTbytecount (); *} *}}-------------------------------------------------------------------<p>this class is Thread-safe. Perform multiple cache operations atomically by * Synchronizing on the cache: <pre> {@code * synchronized (cache) 
{* IF (cache.get (key) = = null) {* CACHE.PUT (key, value); *}}</pre> * He is thread safe, performs multiple cache operations automatically and locks-------------------------<p>this class does not allow NULL to is U Sed as a key or value. A return * value of NULL from {@link #get}, {@link #put} or {@link #remove} are * unambiguous:the key ' "
He. * Do not allow key or value NULL * when get (), put (), remove () return value is NULL, key corresponding item is not in cache

The most important thing is probably the above: use a very simple look at the code

Import Android.graphics.Bitmap;
Import Android.support.v4.util.LruCache;
/**
* Memory Cache Tool Class
* * 
@author Ace
* @date 2016-02-19
/public class Memorycacheutils {

// At the start of the Android 2.3 (API level
//9), the garbage collector prefers to recycle objects that hold soft references or weak references, which makes soft references and weak references less reliable, suggesting using LRUCache, which is strong reference
private Lrucache<string, bitmap> Mcache;
Public Memorycacheutils () {
int maxmemory = (int) runtime.getruntime (). MaxMemory ()//Get maximum memory allocated by virtual machine
/16M
//LRU The least recent use, by controlling the memory not exceeding the maximum (specified by the developer), to solve the memory overflow, as the above translation said if the cache is full will clean up the most recently used cache object
Mcache = new lrucache< String, bitmap> (MAXMEMORY/8) {
@Override
protected int sizeOf (string key, Bitmap value) {
//computes a BITM The size of the AP
int size = value.getrowbytes () * value.getheight ();//The number of bytes per line multiplied by the height return
size;}
;
} Public
Bitmap getbitmapfrommemory (String URL) {return
mcache.get (URL);
}
public void setbitmaptomemory (String url, Bitmap Bitmap) {
mcache.put (URL, Bitmap);
}

Last-level cache local cache saves the picture file name of the network download to the memory card's development directory in MD5 form

/** * Local Cache Tool Class * * @author Ace * @date 2016-02-19/public class Localcacheutils {//Picture cached folder public static final Strin
G Dir_path = environment. getExternalStorageDirectory (). GetAbsolutePath () + "/ace_bitmap_cache"; Public Bitmap getbitmapfromlocal (String url) {try {file file = new File (Dir_path, Md5encoder.encode (URL)); if (File.exis TS ()) {Bitmap Bitmap = Bitmapfactory.decodestream (new FileInputStream (file)); return Bitmap;}
catch (Exception e) {e.printstacktrace ();} return null; public void Setbitmaptolocal (Bitmap Bitmap, String url) {File dirfile = new File (dir_path);//Create Folder folder does not exist or it is not a folder
A folder. Mkdirs,mkdir the difference is that if a folder has several layers of paths, the former creates a missing parent directory that does not create these parent directories if (!dirfile.exists () | |!dirfile.isdirectory ()) {
Dirfile.mkdirs (); try {File File = new file (Dir_path, Md5encoder.encode (URL));//Save picture compression locally, Parameter 1: compression format; parameter 2: Compression quality (0-100); parameter 3: output stream Bitmap.compre
SS (Compressformat.jpeg, new FileOutputStream (file));
catch (Exception e) {e.printstacktrace ();}} }

Md5encoder

Import Java.security.MessageDigest;
public class Md5encoder {public
static string encode (string string) throws Exception {
byte[] hash = messagediges T.getinstance ("MD5"). Digest (String.getbytes ("UTF-8"));
StringBuilder hex = new StringBuilder (Hash.length * 2);
for (byte b:hash) {
if ((b & 0xFF) < 0x10) {
hex.append ("0");
}
Hex.append (integer.tohexstring (b & 0xFF));
}
return hex.tostring ();
}

Finally create a new tool class to use the three cache tool classes above

/** * Level three Cache tool class * * @author Ace * @date 2016-02-19/public class Mybitmaputils {//Network slow
Storage tools private Netcacheutils mnetutils;
Local Cache tool class private localcacheutils mlocalutils;
Memory Cache Tool class private memorycacheutils mmemoryutils; Public Mybitmaputils () {mmemoryutils = new memorycacheutils (); mlocalutils = new Localcacheutils (); mnetutils = new NetCa
Cheutils (Mlocalutils, mmemoryutils); public void display (ImageView imageview, String URL) {//Set default loading picture Imageview.setimageresource (r.drawable.news_pic_
Default);
Load Bitmap Bitmap = mmemoryutils.getbitmapfrommemory (URL) from the memory cache first;
if (bitmap!= null) {Imageview.setimagebitmap (bitmap);
System.out.println ("read pictures from memory ...");
Return
}//Then load bitmap = mlocalutils.getbitmapfromlocal (URL) from the local cache;
if (bitmap!= null) {Imageview.setimagebitmap (bitmap);
System.out.println ("read the picture from the local ...");
Set the picture mmemoryutils.setbitmaptomemory (URL, bitmap) to the memory;
Return
}//Load mnetutils.getbitmapfromnet from the network cache (ImageView, URL); }
}

The above describes the Android asynchronous request picture plus level Three cache knowledge, I hope to help.

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.