From Universal IMAGE LOADER. Part 3 (four displayimage overloaded methods), we learned the use of four displayimage overloaded methods in Android-universal-image-loader (hereinafter referred to as UIL), if you have not yet learned, It's best to go back and see it, or you might not understand the article. In this article we will focus on the main processes of android-universal-image-loader and the analysis of the classes related to these processes.
Let's take a look at the process of UIL loading pictures (you can view the Imageloader.displayimage (...). Method analysis), such as
From this, we can see that the general flow of UIL loading pictures is to determine whether there is a corresponding bitmap in memory, and then determine if there is a disk, if not on the network from the load. Finally, based on the previous configuration in UIL, it is necessary to determine whether the cache bitmap to memory or disk. After the bitmap is loaded, it is parsed and then displayed in a specific imageview.
With UIL's initial understanding of the picture loading and processing process, we can begin to analyze its source code. First from Imageloader.displayimage (...) Start, after all, everything begins with it.
1 public void DisplayImage (String uri, Imageaware imageaware, displayimageoptions options, 2 imageloading Listener Listener, Imageloadingprogresslistener progresslistener) {3//Check whether the configuration of UIL is initialized 4 checkconfiguratio N (); 5 if (Imageaware = = null) {6 throw new illegalargumentexception (error_wrong_arguments); 7} 8 if (listener = = NULL) {9 listener = emptylistener;10}11 if (options = = null) {12 options = configuration.defaultdisplayimageoptions;13}14 (textutils.isempty (URI)) {16 Engine.canceldisplaytaskfor (Imageaware); listener.onloadingstarted (URI, Imageaware.getwrappedview () ), if (Options.shouldshowimageforemptyuri ()) {imageaware.setimagedrawable (Options.getimag Eforemptyuri (configuration.resources)); else {imageaware.setimagedrawable (null); 22 }23 Listener.onloadingcomplete (URI, Imageaware.getwrappedview (), null), return;25}26//calculation B The size of the itmap so that the image is parsed later with ImageSize targetsize = Imagesizeutils.definetargetsizeforview (Imageaware, Configuration.getm Aximagesize ()); String Memorycachekey = Memorycacheutils.generatekey (URI, targetsize); engine.prepared Isplaytaskfor (Imageaware, Memorycachekey); listener.onloadingstarted (URI, Imageaware.getwrappedview ()); 32 is bitmap memory slow? Bitmap bmp = Configuration.memoryCache.get (Memorycachekey), if (BMP! = null &&!bmp.isrecycle D ()) {L.D (Log_load_image_from_memory_cache, memorycachekey); PNS if (options.shouldpostprocess ()) {Imageloadinginfo imageloadinginfo = new Imageloadinginfo (URI, Imageaware, Targetsize, Memorycachek ey,39 options, Listener, Progresslistener, Engine.getlockforuri (URI)); 40//processing and displaying pictures 41 Processanddisplayimagetask displaytask = new Processanddisplayimagetask (engine, BMP, imageloadinginfo,42 Definehandler (options)), if (options.issyncloading ()) {. Dis Playtask.run (); "Else {engine.submit (displaytask); 47}48 } else {49//Display Picture Options.getdisplayer (). Display (BMP, Imageaware, loadedfrom.memory _cache); Wuyi listener.onloadingcomplete (URI, Imageaware.getwrappedview (), BMP); 52}53} else {options.shouldshowimageonloading ()) {imageaware.setimagedrawable (Options.getim Ageonloading (Configuration.resources)); (Options.isresetviewbeforeloading ()) Mageaware.setimagedrawable (null);}59 imageloadinginfo imageloadinginfo = new Ima Geloadinginfo (URI, imageAware, Targetsize, memorycachekey,61 options, Listener, Progresslistener, Engine.getlockforuri (URI)); 6 2//Start a thread, load and display pictures loadanddisplayimagetask displaytask = new Loadanddisplayimagetask (engine, IMA geloadinginfo,64 Definehandler (options)); if (options.issyncloading ()) {66 Displaytask.run (); Engine.submit} else {displaytask); 69}70}71 }
There is a lot of code, but there are many codes for exception handling and function callbacks, in order to grasp the overall process first, we give up the details of the tracking. Basically the process of processing I have useful comments to mark out. However, from this code we can also see that the structure of this code is very clear. The entire loading process of the picture has a corresponding listening interface (imageloadinglistener.onloadingstarted, Imageloadinglistener.onloadingcomplete,imageloadinglistener This class is used to monitor the loading process of the picture, that is, the entire picture loading process programmers can be processed accordingly. We first focus on a piece of the loading process from scratch, after all, this part is the most concerned about. See the Loadanddisplayimagetask in line 63rd, follow the Loadanddisplayimagetask.run () method. In this run () method, in addition to BMP = Tryloadbitmap (), this sentence is to load the picture, the other functions are to bitmap processing or display. Let's go ahead and look.
1 private Bitmap Tryloadbitmap () throws Taskcancelledexception {2 Bitmap Bitmap = null; 3 try {4 Attempt to read from the disk cache bitmap 5 File imagefile = Configuration.diskCache.get (URI); 6 if (ImageFile! = null && imagefile.exists ()) {7 L.D (Log_load_image_from_disk_cache, Memorycachekey); 8 Loadedfrom = Loadedfrom.disc_cache; 9 checktasknotactual (); bitmap = Decodeimage (Scheme.FILE.wrap (Imagefile.getabsolutepa Th ())); 12}13//No cache on disk, download picture from Network if (bitmap = = NULL | | bitmap.getwidth () <= 0 | | Bitmap.getheight () <= 0) {L.D (log_load_image_from_network, memorycachekey); Loade Dfrom = loadedfrom.network;17 String imageurifordecoding = uri;19 if (options.iscacheon Disk () && Trycacheimageondisk ()) {imagefile = Configuration.diskCache.get (uri) if (imagefile! = null) {imageurifordecoding = Scheme.FILE.wrap (imagef Ile.getabsolutepath ());}24}25 checktasknotactual (); 27 Bitmap = Decodeimage (imageurifordecoding); if (bitmap = = NULL | | bitmap.getwidth () <= 0 | | Bitmap.getheight () <= 0) {firefailevent (failtype.decoding_error, null); 31}32 }33} catch (IllegalStateException e) {firefailevent (failtype.network_denied, null); 35 } catch (Taskcancelledexception e) {$ throw e;37} catch (IOException e) {L.E (E ); Firefailevent (Failtype.io_error, E); (OutOfMemoryError e) {L.E (e); 42 Firefailevent (Failtype.out_of_memory, e);) catch (Throwable e) {L.E (e); Irefailevent (Failtype.unkNown, E);}47 return bitmap;48}
From the 3~12 line is an attempt to load bitmap from the disk cache. Line 19th Determines if there is a cache on the disk and begins a network download (Trycacheimageondisk ()). In the Trycacheimageondisk () function, there is a trycacheimageondisk () loaded = Downloadimage () to download the picture.
Private Boolean Downloadimage () throws IOException { InputStream is = Getdownloader (). GetStream (URI, Options.getextrafordownloader ()); Return Configuration.diskCache.save (URI, is, this); }
What this function does is simply to get a Downloader that implements Image Downloader (here, of course, the author divides Downloader into slow (slownetworkdownloader) according to the network situation, Normal speed (downloader), network rejection (Networkdenieddownloader) in the case of download, where we do not expand, you just know that they are the Imagedownloader interface of the implementation of the line, The following article explores this issue) and then writes the bitmap to the disk cache using disk cache. Go back to the Tryloadbitmap () in the Downloadimage () function before we cache the picture on disk. If the cache to disk is related to configuration), immediately after calling bitmap = Decodeimage (Scheme.FILE.wrap (Imagefile.getabsolutepath ())), parse the picture. Entering the Decodeimage () function, we find that UIL calls image Decoder to parse the image.
1 Private Bitmap decodeimage (String Imageuri) throws IOException {2 viewscaletype Viewscaletype = Imageaware.getscaletype (); 3 imagedecodinginfo decodinginfo = new Imagedecodinginfo (Memorycachekey, ImageUri, Uri , Targetsize, viewscaletype,4 getdownloader (), options); 5 return Decoder.decode (decodinginfo); 6 }
The decode () function is finally parsed by invoking the Baseimagedecoder.decode () method, which takes advantage of the previously obtained InputStream, reads the data directly from it, parses it, and resets the network interface for the entire download task.
1 public Bitmap decode (Imagedecodinginfo decodinginfo) throws IOException {2 Bitmap decodedbitmap; 3 Ima Gefileinfo Imageinfo; 4 5 InputStream ImageStream = Getimagestream (Decodinginfo); 6 try {7 Imageinfo = defineimagesizeandrotation (ImageStream, decodinginfo); 8 ImageStream = Resetstream (ImageStream, decodinginfo); 9 Options decodingoptions = Preparedecodingoptions (imageinfo.imagesize, decodinginfo); decodedbi TMap = Bitmapfactory.decodestream (ImageStream, NULL, decodingoptions), one} finally {Ioutils.closesi lently (imagestream);}14 if (Decodedbitmap = = null) {L.E, Deco Dinginfo.getimagekey ()); n} else {decodedbitmap = Considerexactscaleandorientatiton (Decodedbitmap, Decodinginfo, imageinfo.exif.rotation,19 imageInfo.exif.flipHorizontal);}21 return DecodedbitmAP;22}
Next, with the parsed bitmap object, all that remains is to display it in the Image view object. We return to the beginning of the article to introduce the Imageloader.displayimage (...) function (The associated code can be seen at the beginning of the article).
For convenience, I will still be imageloader.displayimage (...) The code involved in this is posted below.
1 displaybitmaptask displaybitmaptask = new Displaybitmaptask (BMP, Imageloadinginfo, engine, Loadedfrom); 2 RunTask (Displaybitmaptask, syncloading, Handler, engine);
Let's go inside the Displaybitmaptask.run () function to see. Except for the Imageloadinglistener.imageloadinglistener () code of the previous lines, the related code is actually a line displayer.display (bitmap, Imageaware, Loadedfrom), it is actually called Bitmapdisplayer this object will bitmap object display to ImageView. According to the different objects that implement the Bitmapdisplayer interface, there are Simplebitmapdisplayer, Fadeinbitmapdisplayer, Roundedbitmapdisplayer, Roundedvignettebitmapdisplayer these 5 kinds of objects.
Finally, let's use the task flow diagram to outline the corresponding interface in the process above.
In the next article, we will introduce the package design, buffering, downloading, multi-tasking mechanism in UIL.
Image loading and display process from code Analysis Android-universal-image-loader