Android efficiently loads large and multi graph solutions to effectively avoid program oom (turn)

The main content of this article comes from Android doc. I have done some processing after translation. Good English friends can also read the original text directly.

http://developer.android.com/training/displaying-bitmaps/index.html

Load large pictures efficiently

We often use many pictures when writing Android programs. Different pictures will always have different shapes and sizes, but in most cases, these pictures will be larger than the size required by our programs. For example, most of the pictures displayed in the system picture library are taken by mobile phone cameras, and the resolution of these pictures will be much higher than that of our mobile phone screen. You should know that the applications we write have a certain memory limit. If the program occupies too much memory, it is prone to oom (OUTOFMEMORY) exceptions. We can see the maximum available memory of each application through the following code.

Therefore, when displaying high-resolution pictures, it is best to compress the pictures first. The size of the compressed image should be similar to the size of the control used to display it. Displaying a large image on a small ImageView will not bring any visual benefits, but it will occupy a lot of valuable memory, and may have a negative impact on performance. Let's take a look at how to properly compress a large picture so that it can be displayed in the best size and prevent the emergence of oom.

Bitmapfactory class provides multiple parsing methods (decodebytearray, decodefile, decoderesource, etc.) to create bitmap objects. We should select the appropriate method according to the source of the image. For example, the picture in the SD card can use the decodefile method, the picture on the network can use the decodestream method, and the picture in the resource file can use the decoderesource method. These methods will try to allocate memory for the built bitmap, which will easily lead to oom. For this purpose, each parsing method provides an optional bitmapfactory Options parameter. Setting the injustdecodebounds property of this parameter to true can make the parsing method prohibit the allocation of memory for bitmap, and the return value is no longer a bitmap object, but null. Although bitmap is null, bitmapfactory The outwidth, outheight and outmimetype properties of options are assigned. This technique allows us to obtain the length width value and MIME type of the picture before loading the picture, so as to compress the picture according to the situation. The following code is shown:

In order to avoid oom exceptions, it is best to check the size of each image before parsing it. Unless you trust the source of the image very much, ensure that these images will not exceed the available memory of your program.

Now that the size of the image is known, we can decide whether to load the whole image into memory or a compressed image into memory. The following factors need to be considered:

For example, your ImageView is only 128 * 96 pixels in size, just to display a thumbnail. At this time, it is obviously not worth loading a 1024 * 768 pixel picture into memory.

How can we compress the picture? By setting bitmapfactory The value of insamplesize in options can be implemented. For example, if we have a picture with 2048 * 1536 pixels and set the value of insamplesize to 4, we can compress the picture into 512 * 384 pixels. Originally, loading this picture requires 13m of memory, but only 0.75m after compression (assuming that the picture is of argb_8888 type, that is, each pixel occupies 4 bytes). The following method can calculate the appropriate insamplesize value according to the incoming width and height:

To use this method, you must first convert bitmapfactory Set the injustdecodebounds property of options to true and parse the picture once. Then bitmapfactory Options are passed to the calculateinsamplesize method along with the desired width and height to get the appropriate insamplesize value. Then parse the image again, use the newly obtained insamplesize value, and set injustdecodebounds to false to get the compressed image.

The following code simply compresses any picture into a 100 * 100 thumbnail and displays it on ImageView.

Using image caching technology

Loading an image on the UI of your application is a very simple thing, but when you need to load a lot of images on the interface, the situation becomes complicated. In many cases (such as using components such as listview, GridView or viewpager), the pictures displayed on the screen can increase continuously through events such as sliding the screen, resulting in oom.

In order to ensure that the use of memory is always maintained within a reasonable range, the pictures of the removed screen are usually recycled. At this time, the garbage collector will also think that you no longer hold the references of these pictures, so as to GC these pictures. It is very good to use this idea to solve the problem, but in order to make the program run quickly and load pictures quickly on the interface, you must consider that after some pictures are recycled, users slide them back into the screen. At this time, reloading the newly loaded image is undoubtedly the bottleneck of performance. You need to find ways to avoid this.

At this time, the use of memory caching technology can solve this problem. It can enable components to reload and process images quickly. Let's take a look at how to use memory caching technology to cache pictures, so that your application can improve response speed and fluency when loading many pictures.

Memory caching technology provides fast access to images that occupy a lot of valuable memory of the application. The core class is lrucache (this class is provided in the android-support-v4 package). This class is very suitable for caching images. Its main algorithm principle is to store the recently used objects in LinkedHashMap with strong references, and remove the least recently used objects from memory before the cache value reaches the preset value.

In the past, we often used the implementation of a very popular memory caching technology, that is, soft reference or weak reference. However, this method is no longer recommended, because starting from Android 2.3 (API level 9), the garbage collector tends to recycle objects holding soft references or weak references, which makes soft references and weak references no longer reliable. In addition, in Android 3.0 (API level 11), the image data will be stored in the local memory, so it is impossible to release it in a predictable way, which has the potential risk of causing memory overflow and crash of the application.

In order to select an appropriate cache size for lrucache, the following factors should be considered, for example:

It's up to you to decide that no specified cache size can meet all applications. You should analyze the memory usage of your program and work out an appropriate solution. A too small cache space may cause images to be released and reloaded frequently, which is not good. If the cache space is too large, it may still cause Java Exception of lang.outofmemory.

The following is an example of using lrucache to cache pictures:

In this example, one eighth of the memory allocated by the system to the application is used as the cache size. In medium and high configuration mobile phones, there will be about 4 megabytes (32 / 8) of cache space. If a full screen GridView is filled with four 800x480 resolution images, it will occupy about 1.5 megabytes of space (800 * 480 * 4). Therefore, this cache size can store 2.5 pages of pictures. When a picture is loaded into the ImageView, it is first checked in the cache of lrucache. If the corresponding key value is found, the ImageView will be updated immediately. Otherwise, a background thread will be started to load the image.

In this example, one eighth of the memory allocated by the system to the application is used as the cache size. In medium and high configuration mobile phones, there will be about 4 megabytes (32 / 8) of cache space. If a full screen GridView is filled with four 800x480 resolution images, it will occupy about 1.5 megabytes of space (800 * 480 * 4). Therefore, this cache size can store 2.5 pages of pictures. When loading a picture into ImageView, 1) "> 11}

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>