Memory Optimization for images in Android

Source: Internet
Author: User

1. Operate the image itself

Try not to use setImageBitmap, setImageResource, BitmapFactory. decodeResource to set a large image, because these methods are completed through the createBitmap on the Java layer after the decode is completed, requiring more memory consumption. Therefore, use BitmapFactory first. the decodeStream method creates a bitmap and sets it as the source of ImageView. The biggest secret of decodeStream is that it directly calls JNI> nativeDecodeAsset () to complete decode, you no longer need to use the createBitmap on the Java layer, thus saving the Java Layer Space. If the configuration parameter of the slice is added during reading, the loaded memory can be reduced more effectively to prevent memory exceptions from being thrown. In addition, decodeStream directly reads bytecode from images and does not automatically adapt to various machine resolutions. After decodeStream is used, it must be in hdpi and mdpi, configure the corresponding image resources in ldpi. Otherwise, the images are of the same size (number of pixels) on machines with different resolutions. The displayed size is incorrect.

Copy codeThe Code is as follows: InputStream is = this. getResources (). openRawResource (R. drawable. pic );
BitmapFactory. Options options = new BitmapFactory. Options ();
Options. inJustDecodeBounds = false;
Options. inSampleSize = 2;
Bitmap btp = BitmapFactory. decodeStream (is, null, options );

The above Code reads the thumbnail of the pic image under drawable. The length and width are only 1/2 of the original image. The image size is reduced, and the memory occupied is naturally reduced. The disadvantage of this is that the image quality is deteriorated. The larger the value of inSampleSize, the worse the image quality. Because mobile phone manufacturers have different Image Scaling algorithms, the image quality on different mobile phones may be different.

2. Call the recycle () method of the image

Copy codeThe Code is as follows: if (! Bmp. isRecycle ()){
Bmp. recycle () // reclaim the memory occupied by the image
System. gc () // remind the system to recycle it in time
}

This method is not actually a way to actually reduce the image memory. The main purpose is to mark the image object to facilitate the collection of local data of the image object. The local data of the image object occupies the largest memory and is calculated separately from the Java memory of the program. Therefore, Java heap is often enough, and the image has an OutOfMemoryError. This method can be called when the image is not in use, effectively reducing the peak value of the local data of the image, thus reducing the probability of OutOfMemoryError. However, the image object that calls recycle () is in the "obsolete" state, which may cause a program error. Therefore, this method is not recommended when it cannot guarantee that the image object will never be called again. Note that setImageBitmap (Bitmap
Img) the image object allocated to the control by the method may be called by the system library, resulting in a program error.

3. Read images of local resources in the most memory-saving manner

Copy codeThe Code is as follows :/**
* Read images of local resources in the most memory-saving manner
*/
Public static Bitmap readBitMap (Context context, int resId ){
BitmapFactory. Options opt = new BitmapFactory. Options ();
Opt. inPreferredConfig = Bitmap. Config. RGB_565;
Opt. inPurgeable = true;
Opt. ininputtransferable = true;
// Obtain the resource Image
InputStream is = context. getResources (). openRawResource (resId );
Return BitmapFactory. decodeStream (is, null, opt );
}

Android supports four color modes: ALPHA_8: each pixel occupies 1 byte memory, ARGB_4444: each pixel occupies 2 bytes of memory, and ARGB_8888: each pixel occupies 4 bytes of memory and RGB_565: each pixel occupies 2 bytes of memory. The default color mode for Android is ARGB_8888. This color mode features the most delicate colors and the highest display quality. However, the memory is also the largest. The above Code reads the image resource in RGB_565 (or ARGB_4444) mode. Although the memory reduction is not as obvious as the first method, most images cannot see any difference with the ARGB_8888 mode. However, when reading images with gradient effects, there may be color bars. In addition, it will affect the special effect processing of the image.

4. How to change the color mode of an image zoomed in with a Matrix object:

Although using a Matrix object to enlarge an image will consume more memory, sometimes you have to do the same. The enlarged image uses the ARGB_8888 color mode, even if the original image is in the ARGB_4444 color mode, and there is no way to directly specify the color mode when you zoom in. You can change the image color mode in the following ways.

Copy codeThe Code is as follows: Matrix matrix = new Matrix ();
Float newWidth = 200; // The enlarged width of the image.
Float newHeight = 300; // The enlarged image Length
Matrix. postScale (newWidth/img. getWidth (), newHeight/img. getHeight ());
Bitmap img1 = Bitmap. createBitmap (img, 0, 0, img. getWidth (), img. getHeight (), matrix, true); // enlarge the image
Img2 = img1.copy (Bitmap. Config. ARGB_4444, false); // obtain the image in the ARGB_4444 color mode.
Img = null;
Img1 = null;

An additional image object img1 is generated compared to the original image. However, the system will take over img1, so the actual memory is reduced.

In summary, reading images in the thumbnail mode and reducing the memory occupied by each pixel in the image is the most effective. These two methods are effective, but they also have their own drawbacks. In actual development, it should be applied according to the scene as appropriate. The most important way is to avoid the generation of junk objects. For example, you can reuse convertView in a ListView application. If you use AsyncTask to load images, you must promptly set the referenced ImageView object to null. Because AsyncTask is implemented by a thread pool, the referenced object may have a long life cycle and GC cannot be released. I still trust the Android memory receiving and taking over mechanism. recycle is certainly effective to some extent, but I always feel that it is not suitable for Java memory receiving and taking over.

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.