24.7 Challenge Exercise: preloading and caching
Not all tasks in the application can be completed in real time, and most users understand that. But even so, developers have been trying to do their best. To make the application more responsive, most real-world applications enhance their code in the following two ways:? Increase the cache layer
? Pre-load Picture
Caching refers to the place where a certain number of Bitmap objects are stored. This way, they are still stored there, even if they are no longer used.
There is a limited amount of storage space for the cache, so when the cache space is exhausted, a certain strategy is needed to make a trade-off of the saved objects. Many caching mechanisms use a storage strategy called LRU (least recently used, least recently used). Based on this strategy, when storage space is exhausted, the cache clears the least recently used objects. The LruCache class in the Android support library implements the LRU cache policy.
As the first challenge exercise, use LRUCache to add a simple caching feature to the Thumbnaildownloader. In this way, each time the Bitmap is downloaded, it is stored in the cache. Then, when you are ready to download a new picture, you should first check the cache to see if it exists. Once the cache implementation is complete, you can use it to preload. Preloading refers to the pre-loading of processing objects into the cache before actually using the object.
This way, when the Bitmap is displayed, there is no download delay. Achieving a perfect preload is tricky, but for users, good preload is a very different experience. As a second, slightly more challenging exercise, preload the first 10 and next 10 galleryitem when displaying Galleryitem Bitmap
1. Increase the cache layer
in the Thumbnaildownloader Increase:
Private Lrucache<string, bitmap> Mbitmaplrucache;
Instantiate this object in the Onlooperprepared () method:
//onlooperprepared () is called before Looper checks the message queue for the first time. @Overrideprotected voidonlooperprepared () {Mrequesthandler=NewHandler () {@Override Public voidHandlemessage (Message msg) {//the call to the Handler.handlemessage () method is triggered when the download message in the queue is taken out and can be processed. if(Msg.what = =message_download) {T target=(T) msg.obj; LOG.I (TAG,"Got a request for URL"+ Mrequestmap.Get(target)); HandleRequest (target); } } }; Mbitmaplrucache = new lrucache<string, bitmap> ( * 1024x768 )); //In practice, LRUCache allocated memory should be dynamically calculated }
To modify the HandleRequest () method:
Private voidhandlerequest (final T target) {Try{final String URL= Mrequestmap.Get(target); Final Bitmap Bitmap; if(url = =NULL) { return; } if(Mbitmaplrucache.Get(URL)! =NULL) {Bitmap= Mbitmaplrucache.Get(URL); } Else { byte[] Bitmapbytes =NewFlickrfetcher (). geturlbytes (URL); Bitmap= Bitmapfactory.decodebytearray (Bitmapbytes,0, bitmapbytes.length);//Converts the returned byte array to a bitmap } if(Mbitmaplrucache.Get(URL) = =NULL) {mbitmaplrucache.put (URL, bitmap); LOG.D (TAG,"handlerequest:put---"+ URL); } log.i (TAG,"Bitmap Created"); Mresponsehandler.post (NewRunnable () {@Override Public voidrun () {if(Mrequestmap.Get(target)! = URL | | Mhasquit) {//check Requestmap again because Recyclerview will cycle through its view, return; } mrequestmap.remove (target); //Delete paired photoholder-url in Requesmapmthumbnaildownloadlistener.onthumnaildownloaded (target, bitmap); } }); } Catch(IOException IoE) {log.e (TAG,"Error Downloading Image", IoE); }}
2. Pre-load:
In Photogalleryfragment
@Override Public voidOnbindviewholder (Photoholder Photoholder,intposition) {Galleryitem Galleryitem= Mgalleryitems.Get(position); Drawable Placeholder=getresources (). getdrawable (R.drawable.bill_up_close); photoholder.binddrawable (placeholder); Mthumbnaildownloader.queuethumbnail (Photoholder, Galleryitem.geturl ()); for (int i=position-; i<position + ten; i++) {// It must be put in LRUCache before the picture is displayed. Very time consuming if (i < 0 | | i = = Position | | I >= mitems.size ()) { continue; } galleryitem Item = Mgalleryitems. Get (i); Mthumbnaildownloader.puturl (Item.geturl ()); }}
In Thumbnaildownloader:
Public voidputurl (final String URL) {if(Mbitmaplrucache.Get(URL) = =NULL){ NewThread (NewRunnable () {@Override Public voidrun () {Try{ byte[] Bitmapbytes =NewFlickrfetcher (). geturlbytes (URL); Bitmap Bitmap= Bitmapfactory.decodebytearray (Bitmapbytes,0, bitmapbytes.length); Mbitmaplrucache.put (URL,BITMAP); }Catch(Exception e) {e.printstacktrace (); }}). Start (); } }
Android authoritative Programming Guide Challenge Exercise 24 pre-loading and caching