Why is it not recommended to use UniversalImageLoader to load res/drawable and imageloaderdrawable?

Source: Internet
Author: User

Why is it not recommended to use UniversalImageLoader to load res/drawable and imageloaderdrawable?
Preface

UniversalImageLoader is a widely used library, which is easy to use and easy to compile. Many large companies use this library and recently encountered a strange bug, I stepped on a UIL trap. Although the author reminded us on the wiki, I didn't understand the meaning of this sentence until I found the cause of the bug.

A strange bug

There is a self-painted control in the project, which is a Download button. After clicking it, the current download progress is displayed. Recently, we found that the picture displayed by this button on a 2.3.7 and a 4.2.2 is incorrect, other mobile phones are normal, but after debugging, the button is foundonDrawThere is no problem with method calling, while the image isres/drawableDirectory.pngFile, it is reasonable to say that such images cannot be read incorrectly.
By rolling back the commit, we locate a merge commit, which is the merge from the function development branch back to the main line. After carefully reviewing the commit, we found that this commit did not change the code of the button at all, the image resources used by the buttons have not been tampered with. We submit changes one by one locally and find that as longres/drawableWhen an xml file is added to the directory, the button image will be disordered and added to all xml file names.wtf_Prefix, then the bug on the two mobile phones disappears, but all other normal machines start to have bugs again.
Then I checkedR.javaThe image used by the buttons in the file has a unique id. decompile the installation package, the id andpublic.xmlIf the IDs are the same and the IDs are not the same, we thought it was an android bug that caused the wrong image to be loaded.

UIL's shocking bug

Then you can view the self-painted controls.onDrawMethod, I see that he usedImageLoader.loadImageSyncMethod to obtain the image he needs.drawable://[R.drawable.picname]This ImageLoader custom protocol for readingres/drawableNon-9patch images in the directory. I asked him why he was doing this. He said that the ImageLoader cache mechanism could be used to reduce the file IO when reading images. Well, no problem.
Although I believe that UIL has been used for so long, it is impossible to have a bug that is so serious as reading the wrong picture, but for the purpose of troubleshooting the bug, we still tested it. The test method is very simple:
FourImageView, Two use native APIssetImageResourceLoad A and B respectively, and use the other twoImageLoader.loadImageSyncThe methods are used to Load Diagram A and diagram B respectively.res/drawableDirectory.
The results surprised me that the two images loaded by UIL are exactly the same. UIL is the root of the bug.
At that moment, I felt like I had discovered a shocking bug in UIL. however, I guess it must be something wrong with us. I remember that we do not recommend using ImageLoader to load drawable on the official wiki. We suggest using native methods. Is it because we are stuck in the trap?

Trace UIL

Go back to debug and find that the disordered drawable corresponds to two files in the memory, which should be cached on the disk by ImageLoader. The default configuration for the drawable is to cache images on both the memory and disk, I opened the two files and found them as a graph. I wondered how it would happen.
After carefully reading the source code of ImageLoader, we mainly look at how it handles drawable. We didn't find any exceptions that may cause it to load wrong images, but it will cache the drawable in the memory, the file name is R. drawable. name is calculated by MD5.
To obtain an image, ImageLoader first checks whether the image is in memorycache. If the image is not checked in diskcache, the method used to identify the image in diskcache is to perform MD5 operations on its URI, if the file corresponding to the file name exists in diskcache, decode the file into a bitmap for the app.
At that time, I had cached images on my mobile phone. I want to see how ImageLoader read the images corresponding to the two IDs into one, clear the data, and debug them, unexpectedly, the image read this time is correct. I remember that we asked ImageLoader to cache images on the disk ......

Our pot

ImageLoader helps us cache images on disks and use the MD5 value of drawable id as the file name.
Android development often encountersR.javaCannot be generated.R.javaIt records the IDs of many resource files. This is all done by eclipse, so that android can find the corresponding resources through these IDs. IDs are generated in the same order.res/drawableAdd an xml file in, the id generated by drawable will inevitably change, and the id corresponding to some drawable will be + 1, if the id of a graph of version 1.0 is 0x00000001, the id of Figure B is 0x00000002. If we add a C image in version 2.0, the generated id may be image a 0x00000002, and image B 0x00000003.
If we ignore the MD5 process and directly think that ImageLoader uses id as the file name (the principle is the same, but MD5 is better). If we have used mobile phones of version 1.0, diskcache already has0x00000001.png (image a of version 1.0)And0x00000002.png (diagram B of version 1.0)Two files, upgraded to version 2.0. When the app loads a graph with ImageLoader, it will use the latest id 0x00000002 of image a for searching. At this time, the disk exactly has0x00000002.png (diagram B of version 1.0)So ImageLoader loads graph B to the memory, and the bug occurs.

Solution

Recommendation: Use ImageLoader to loadres/drawableTime is boundcacheOnDiskSetfalse.
Of course, you can also modify the source code of UniversalImageLoader. After all, drawable itself can be understood as having permanently cached resources on the disk. If such resources are not in memorycache, directly request through the system api instead of reading the diskcache managed by the user. Of course, this method will make the Code look a little unuseful. We do not recommend this change.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Related Article

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.