Kjframeforandroid Framework Project Address: https://github.com/kymjs/KJFrameForAndroid
or alternate address http://git.oschina.net/kymjs/KJFrameForAndroid
Kjframeforandroid Development Group: 257053751
As we all know, when the computer reads the data: The memory read speed is the fastest, then the file reads the speed, finally is the network resource reads.
It's too expensive to assume that every time you load the same picture from the Web. So it's enough to get the same picture just once from the network, then cache it locally and load it from the cache after loading the same image. Reading pictures from the memory cache is the fastest, but because Android has a limit on the amount of memory each app can use, it's best to add a file cache. The file cache space is also not infinite, the larger the capacity, the lower the reading efficiency, this is very good understanding, from the desert to find a missing needle and a needle from the plate, which easy to know. So we often set a finite size analogy of 10M.
So, the process of loading the picture should be:
1, first from the memory cache, take the return, not to take the next step;
2, from the file cache, take the return and update to the memory cache, the next step is not taken;
3, download pictures from the network, and update to the memory cache and file cache.
If you just want to know that the file cache is common to the memory cache, check the next blog post.
In the past, we often used the implementation of a very popular memory caching technique, either soft or weak (SoftReference or weakreference). But according to Google's description: This is no longer recommended, because from the Android 2.3 (API Level 9), the garbage collector is more inclined to reclaim the object holding soft or weak references, which makes soft references and weak references become less reliable. In addition, in Android 3.0 (API level 11), the picture's data is stored locally in memory, so it cannot be released in a predictable way, which poses a potential risk for the application's memory overflow and crashes.
Therefore, many of our other is to use the LRU algorithm (Least recently used least recently used algorithm) originally such an algorithm is used in the operating system scheduling. His principle is to store the data through a linear table, and record the number of times each call, the more often used to rank the more forward, the less the use of the ranking is more up, assuming a new increase in data, it will put it in the first place, and then remove the last data. Here is how the memory LRU algorithm is implemented in the Kjframeforandroid framework Lrumemorycache
Since it is loaded into the network image, then of course, the control and network image address to be loaded as a reference, the ratio of the following see
private void LoadImage (ImageView ImageView, String imageUrl) { //first visit the memory cache, infer if the picture already exists Bitmap Bitmap = Mmemorycache.get (STRINGUTILS.MD5 (IMAGEURL)); if (bitmap! = null) { imageview.setimagebitmap (bitmap); } else{ //Otherwise go to network download bitmapworkertask task = new Bitmapworkertask (imageView); Task.execute (IMAGEURL); }}
As for the actual download method, I do not specifically explain, I believe everyone can think of, is a network request, and then download the image, then to bitmap, and finally set as a control picture. However, there is a need to pay attention to the important place, that is, when we download the image after the successful memory in the Mmemorycache cache.
Here is the code for a network image loaded in the Kjfraemforandroid application Development framework:
/********************* asynchronously gets bitmap and sets the task class for image *********************/Private class Bitmapworkertask extends Asynctask <string, Void, bitmap> {private View imageView; Public Bitmapworkertask (View imageview) {this.imageview = ImageView; } @Override protected Bitmap doinbackground (String ... params) {Bitmap Bitmap = null; For this method, the following article will explain byte[] res = downloader.loadimage (params[0]); if (res! = null) {bitmap = Bitmapcreate.bitmapfrombytearray (res, 0, res.length, con Fig.width, Config.height); } if (bitmap! = null && Config.openmemorycache) {//The picture is loaded and cached into Lrccache Putbitmaptomemory (Params[0], bitmap); if (config.isdebug) Kjloger.debuglog (GetClass (). GetName (), "put to memory CA che\n "+ params[0]); } RETUrn bitmap; } @Override protected void OnPostExecute (Bitmap Bitmap) {super.onpostexecute (BITMAP); if (ImageView instanceof ImageView) {if (bitmap! = null) {((ImageView) imageView). s Etimagebitmap (bitmap); }} else {imageview.setbackgrounddrawable (new bitmapdrawable (bitmap)); } if (Config.callback! = null) config.callBack.imgLoadSuccess (ImageView); Taskcollection.remove (this); } }
in-depth understanding of the application of image loading in real-world projects :
The above is just the basic operation of loading and caching the network pictures, then we assume that the use of the actual project must take into account the completeness and extensibility of the code.
① For example, we want to specify the size of the image, although we can force the image size by setting the fixed width of the view, but suppose it is a few megabytes of picture, and we just need to 15*15 the resolution size of the display area, which is obviously wasteful;
② For example, we want the control to display a default image (such as a gray avatar) when the network is downloading the picture, or to display a circular progress bar when the picture is downloaded, then the code above is not available;
③ again, we want to download a variety of images, for different site sources have different ways to download ....
These special needs tell us that the above code is completely out of the way. So for the completeness and scalability of the control, we need a configurator, a monitor, a downloader. And so on special needs to join the plug-in development.
Therefore, we can see Kjbitmapconfig, I_imageloder, i_ under the Org.kymjs.aframe.bitmap package of the kjframeforandroid framework. Display, and so on, with a final decorated class or protocol interface.
For example, the Kjbitmapconfig class, which is a final decorated Configurator class, allows us to dynamically set the width, memory size, and so on for each downloaded image. And I_imageloder, I_display is two protocol interface, respectively, defines the method of the downloader and display, here is actually GOF design pattern in the application of the factory method, just the factory here is not actually used to create objects, but to define the display method or download method, Regardless of the actual factory that implements the I_imageloder abstract factory, there must be a way to load the image. In the actual application of the project, it is possible to invoke the factory loading image, regardless of the actual factory of the downloader.
/** * Picture Loading interface protocol, you can define the download to implement this protocol * * @explain The use of factory method mode design of the downloader, this class is also an abstract factory class for the production of byte[] products * @author KYMJS ([email protected ]) * @version 1.0 * @created 2014-7-11 */public interface I_imageloder {public byte[] LoadImage (String imageUrl);}
Here we should be able to see the code snippet in the above code for a reason.
byte[] res = downloader.loadimage (params[0]);
Downloader is actually the abstract factory of the downloader.
As for the logic of the display and the downloader is the same, here I do not specifically introduced, you can view the Kjframeforandroid source code or Demo sample project.
Here is an implementation of the I_imageloader Downloader protocol Downloader.java, we can certainly be based on their own needs to implement their own downloader, this is not whatever as the expansion of the trial development, which for the image set code itself no matter what the impact.
Kjframeforandroid Framework Learning----setting up network images efficiently