1. Operate on the picture itself
Try not to use Setimagebitmap, Setimageresource, Bitmapfactory.decoderesource to set up a larger picture, because these methods after the completion of decode, ultimately through the Java layer CreateBitmap to complete, the need to consume more memory. Therefore, instead of creating a bitmap by using the Bitmapfactory.decodestream method first and then setting it to the ImageView Source,decodestream the biggest secret is its direct invocation jni>> Nativedecodeasset () to complete the decode, no longer use the Java layer of CreateBitmap, thereby saving the Java layer of space. If you add a picture's Config parameter to the read, you can more efficiently reduce the memory that is loaded, thereby preventing the throwing of memory exceptions more effectively. In addition, Decodestream directly to the image to read byte code, will not be based on the machine's various resolutions to automatically adapt to the use of decodestream, the need to configure the hdpi and mdpi,ldpi in the corresponding picture resources, Otherwise, in different resolution machines are the same size (number of pixels), the display of the size is not correct.
Copy Code code 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 is read drawable under the name pic picture thumbnail, length, width is only the original picture of 1/2. The size of the picture is reduced and the memory footprint is naturally smaller. The disadvantage of this is that the picture quality is bad, the larger the value of the insamplesize, the worse the quality of the picture. Because each handset manufacturer scales the picture the algorithm to be different, on the different handset's scaling picture quality may be different.
2. Call the Recycle () method of the picture
Copy Code code as follows:
if (!bmp.isrecycle ()) {
Bmp.recycle ()//Reclaim the memory occupied by the picture
System.GC ()//reminding system to be recycled in time
}
This is not really a way to reduce the memory of the image. The main purpose is to mark the object of the picture to facilitate the collection of local data of the image object. The picture object's local data occupies the largest amount of memory and is calculated separately from the memory in the program's Java section. So often appear Java heap enough to use, and the picture occurs outofmemoryerror situation. Calling this method when the picture is not in use can effectively reduce the peak value of the local data in the picture, thereby reducing the probability of outofmemoryerror. However, a picture object that calls Recycle () is in an "obsolete" state, causing a program error when invoked. Therefore, it is not recommended to use this method when there is no guarantee that the picture object will never be called again. Special attention has been paid to the use of Setimagebitmap (Bitmap
IMG) method is assigned to a control's picture object and may be invoked by the System class library, causing a program error.
3. Read a picture of local resources in the most memory-saving way
Copy Code code as follows:
/**
* Pictures of local resources in the most memory-saving way
*/
public static Bitmap Readbitmap (context context, int resid) {
Bitmapfactory.options opt = new bitmapfactory.options ();
Opt.inpreferredconfig = Bitmap.Config.RGB_565;
Opt.inpurgeable = true;
Opt.ininputshareable = true;
Get a picture of a resource
InputStream is = Context.getresources (). Openrawresource (RESID);
Return Bitmapfactory.decodestream (is,null,opt);
}
There are four different color modes for loading pictures in Android: alpha_8:1byte memory per pixel, argb_4444:2byte memory per pixel, argb_8888: Each pixel occupies 4byte memory, rgb_565: each pixel occupies 2byte of memory. The Android default color mode is argb_8888, the color mode is the most exquisite color, display the highest quality. But again, the memory footprint is the largest. The above code reads the picture resource in rgb_565 (or argb_4444) mode. Memory reduction Although not as obvious as the first method, for most pictures, there is no difference between the argb_8888 mode and the model. However, when you read a picture with a gradient effect, a color bar may appear. In addition, will affect the image of the special effects processing.
4. How to change the color mode by using a magnified picture of the Matrix object:
Even if you use the Matrix object to enlarge the picture, it will consume more memory, but sometimes you have to. The enlarged image uses the argb_8888 color mode, even if the original picture is argb_4444 color mode, and there is no way to directly specify the color mode when zooming in. You can change the picture color mode using the following methods.
Copy Code code as follows:
Matrix matrix = new Matrix ();
float newwidth = 200; The width of the picture when enlarged
float newheight = 300; The length of the picture enlarged
Matrix.postscale (Newwidth/img.getwidth (), Newheight/img.getheight ());
Bitmap IMG1 = Bitmap.createbitmap (img, 0, 0, img.getwidth (), Img.getheight (), Matrix, true);/get enlarged picture
Img2 = Img1.copy (Bitmap.Config.ARGB_4444, false); Get a picture of the argb_4444 color pattern
img = NULL;
IMG1 = null;
This creates an additional image object img1 than the original picture. But the system will take the initiative to accept the IMG1, so the actual memory has been cut.
The
boils down to the most efficient way to read pictures in thumbnail mode and to cut the memory occupied by each pixel in the picture. These two methods are effective, but also have their own shortcomings. The actual opening or should be applied according to the scene as appropriate. The most kingly way is to avoid the generation of garbage objects. For example, in the application of ListView, multiplexing Convertview and so on. If you use Asynctask to load the picture, make the referenced ImageView object null in time. Because the Asynctask is implemented with a thread pool, the object referenced in this may have a long lifecycle, causing the GC to fail to acquit. I still rely on Android's memory acceptance takeover mechanism, recycle, which is certainly effective, but always feels unsuitable for the principle of Java memory acceptance takeover.