Loading process:
if (memory hit) {read from memory}else{the multiple runnable in the Create Asynctasks,task are dispatched through the stack's advanced and out-of-the-box, rather than queue-first-out, to first load the pictures that the user recently scratched or opened. Asynctask://do in background--the background process pauses when the user scroll the list, reducing the CPU overhead when the list is being scratched, which is also used by Imageloader and Facebook's official app. If (disk cache hit) {read from cache}else{after successful download from the network, save to disk cache and memory}
Memory Picture ManagementLruCache, with a capacity of 1/10 runtime memory. In Nexus 4, for example, memory 2G,JVM allocates 512MB of available memory for the sample app, so the image LRUCache size in memory is 51.2MB. When the capacity is reached, do not directly recycle bitmap, but add bitmap to a weakreference map, otherwise on the small memory phone, it is likely to recycle off some of the bitmap is also referenced.
Cached Picture ManagementChocolatecache, policy similar to LRUCache, but optimized for IO read and write speed and hit rate (acknowledgement Berquis)
Considerations for downloading and parsing picturesBlack Chart problem: //If the byte[is not generated based on this fixed length], it is directly decode // InputStream , will cause black image (picture appears black rectangle)Imgdata =
New
byte[length];
byte[] temp =
New
byte[+];
intreadlen = 0;
intdestpos = 0;
while((Readlen = Minputstream.read (temp)) > 0) {system.arraycopy (temp, 0, Imgdata, Destpos, Readlen);Destpos + = Readlen; }Model and network compatibility issues: Samsung NOTE3 in the CDMA network is the Gzipinputstream (length is-1), the other models and scenes are Fixedlengthinputstream (length is the normal size), So when Length=-1, a byte array of images is generated using the most basic Inputstream->outputstream->bytearray way The automatic scaling problem (especially the emoticon module) when different resolutions are displayed should use Bitmapfactory.decodestream instead of Bitmapfactory.decodebytearray, because the latter in the source Density to target density is not automatically scaled when converted. For example, a 250x250 picture, the default density is 320, but LG's G2 phone density is 480, so this picture should be scaled to 480/320=1.5 and displayed on the G2 phone. However, the image obtained after Decodebytearray is still 250x250, but if you use decodestream you will get a picture with a long width of 250*1.5=375, thus achieving the best display effect. root cause See source code:
Public
StaticBitmap Decodestream (InputStream is, Rect outpadding, Options opts) { ... ...
if(opts = =
NULL|| (OPTs.inscaled&& opts.Inbitmap==
NULL)) {
floatScale = 1.0f;
inttargetdensity = 0;
if(opts! =
NULL) {
Final
int density = opts.indensity;targetdensity = opts.intargetdensity;
if(Density! = 0 && Targetdensity! = 0) {Scale = targetdensity/(
float) density;
//Note that there is a calculation of the scale, and
Decodebytearray This operation is not done
} } BM =
Nativedecodeasset(Asset, Outpadding, opts,
true, scale);
if(BM! =
NULL&& targetdensity! = 0) bm.setdensity (targetdensity); finish =
false; }
Else{BM =
Nativedecodeasset(Asset, Outpadding, opts); } }... ...
Public
StaticBitmap Decodebytearray (
byte[] Data,
int Offset,
intlength, Options opts) {
if((offset | length) < 0 | | data.length< offset + length) {
Throw
Newarrayindexoutofboundsexception (); }Bitmap BM =
Nativedecodebytearray(data, offset, length, opts);
if(BM = =
NULL&& opts! =
NULL&& opts.Inbitmap!=
NULL) {
Throw
NewIllegalArgumentException ("problem decoding into existing bitmap"); }
returnBM; }
Scenario StrategyThe network picture handles the local picture or the photograph picture according to the original size, because is often the high definition large picture, therefore needs to set the sampling rate according to the situation, reduces the memory consumption when decode bitmap and write to cache (acknowledgement wind)