When Android loads a large background image or a large number of images, it often results in memory overflow (out of the memories Error), this article according to my experience in dealing with these issues and other developers experience, the following (some code and text source can not be verified):
scenario One, read the picture when the call to note the method, appropriate compressionTry not to use
SetimagebitmapOr
SetimageresourceOr
Bitmapfactory.decoderesourceTo set up a larger image, because these functions are eventually passed through the Java layer after the decode is completed.
CreateBitmapTo complete, you need to consume more memory. Therefore, instead of first passing
Bitmapfactory.decodestreammethod, create a bitmap, and then set it to the source of ImageView,
DecodestreamThe biggest secret is that it directly calls Jni>>nativedecodeasset () to complete the decode, eliminating the need to use the Java layer's createbitmap, thus saving the Java layer space.
InputStream is = this. Getresources (). Openrawresource (R.DRAWABLE.PIC1);
Bitmapfactory.options Options = new bitmapfactory.options ();
Options. Injustdecodebounds = false;
Options. insamplesize = 10; // width,hight set as the original very one
Bitmap BTP = bitmapfactory. Decodestream (IS, null, options);
If the config parameter is added at the time of reading, it can be followed by effectively reducing the loaded memory, thereby effectively blocking the throw out of the "Memories" exception.
/**
* Read pictures of local resources in the most memory-saving way
* @param Context
* @param resId
* @return
*/
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);
}
In addition, Decodestream directly take pictures to read bytecode, not according to the machine's various resolutions to automatically adapt, after using the Decodestream, you need to configure the corresponding image resources in hdpi and mdpi,ldpi. Otherwise the same size (number of pixels) is the same on different resolution machines, and the displayed size is wrong.
scenario two, in due time to recover the memory occupied by the pictureUsually activity or fragment can release a picture resource at Onstop/ondestroy time:
if (ImageView! = null && imageview.getdrawable ()! = null) {
Bitmap Oldbitmap = ((bitmapdrawable) imageview.getdrawable ()). Getbitmap ();
Imageview.setimagedrawable (null);
if (Oldbitmap! = null) {
Oldbitmap.recycle ();
Oldbitmap = null;
}
}
Other code.
System. GC ();
When releasing resources, it is important to note whether the released bitmap or related drawable are referenced by other classes. If the call is normal, you can use the
bitmap.isrecycled ()method to determine if it is being tagged for recycling, and if it is used by UI-related code, you need to be very careful not to reclaim resources that might be used, or you might throw a system exception: E/androidruntime: Java.lang.IllegalArgumentException:Cannot Draw recycled bitmaps and the exception cannot be effectively captured and processed.
scenario Three, unnecessary time to avoid the full loading of picturesJust need to know the picture size of the case, can not fully load the picture into memory. When using
bitmapfactoryWhen compressing a picture,
bitmapfactory.optionsSet up
InjustdecodeboundsIs true, then use the
decodefile ()And so on, you can calculate the size of the picture in the non-allocated space state. Example:
Bitmapfactory.options opts = new bitmapfactory.options ();
Set injustdecodebounds to true
OPTs. injustdecodebounds = true;
Use the DecodeFile method to get the width and height of the picture
Bitmapfactory. DecodeFile (path, opts);
Print out the width and height of the picture
Log. D ("Example", opts. Outwidth + "," + opts. Outheight);
(PS: The principle is actually through the picture's head information to read the basic information of the picture)
scenario four, optimizing heap memory allocation for Dalvik virtual machinesThe heap is the most memory-intensive part of the VM and is typically dynamically allocated. The size of the heap is not immutable, and there is usually an allocation mechanism to control its size. For example, the initial heap is 4M large, when 4M space is occupied more than 75%, the redistribution heap is 8M large, when 8M is occupied more than 75%, the allocation heap is 16M large. Upside down, when the 16M heap utilization is less than 30%, the size of the reduction is 8M large. The size of the heap, especially compression, usually involves a copy of the memory, so the size of the change heap has an adverse effect on efficiency. Heap utilization is the utilization of heaps. When the actual utilization deviates from this percentage, the virtual opportunity adjusts the heap memory size in the GC, allowing the actual occupancy rate to converge to a percentage. Use
Dalvik.system.VMRuntimeclass provides the
settargetheaputilizationMethod can enhance the processing efficiency of the program heap memory.
Private final static float target_heap_utilization = 0.75f;
can be called when the program is OnCreate
Vmruntime.getruntime (). Settargetheaputilization (target_heap_utilization);
scenario Five, custom heap (heap) memory sizeFor some Android projects, the main impact of the performance bottleneck is Android's own memory management mechanism, the current handset manufacturers are stingy with RAM, for the smoothness of software, RAM is very sensitive to the performance, in addition to optimizing the Dalvik virtual machine heap memory allocation, We can also enforce the memory size of our own software, and we use the Dalvik provided by
Dalvik.system.VMRuntimeclass to set the minimum heap memory as an example:
Private final static int cwj_heap_size = 6 * 1024x768 *;
Vmruntime.getruntime (). Setminimumheapsize (Cwj_heap_size); //Set minimum heap memory to 6MB size.
But there is still a problem with the above method, the function
setminimumheapsizeIt just changes the lower limit of the heap, it prevents too frequent heap memory allocations, and when setting the minimum heap memory size above the upper limit (Max heap size) still uses the heap's upper bound value, which is not useful for low memory. At last, we introduce the memory algorithm of the occupied process. The base class for working with images in Android is bitmap, as the name implies, bitmaps. Memory-intensive algorithms such as: Width*height*config of images. If config is set to argb_8888, then the config above is 4. A 480*320 picture takes up memory that is 480*320*4 byte. The memory footprint of the Android process is 16M by default, because bitmap he holds data in addition to Java, the underlying C + + Skia Graphics library holds a Skbitmap object, so the general picture should not exceed 8M in memory recommended size. This can be adjusted, you can set the parameters when compiling the source code.turn: http://zwkufo.blog.163.com/blog/static/2588251201312864034812/"
Android loading image causes memory overflow