Android big picture load Memory optimizer (how to prevent outofmemory)

Source: Internet
Author: User

First, Introduction

Mobile devices continue to evolve today, some people think that the memory is large enough, no need to control what memory optimization, Java is a virtual machine can help me maintain memory. In fact, memory space resources are still very valuable, no matter how big the phone memory, the system allocated to a single application of memory space is still very limited roughly 16m,64m,128m, etc. Loading large images in Android consumes system resources very much, and 16M images can store 3 images of 1024x1536 quality of argb_8888, which do not contain any other object's resources. The software runs on the system, the environment is very complex, it is possible to test a limited number of test times did not find a memory leak problem, but in thousands of users in the process, there will always be a variety of memory leak problems.

the calculation rules of the memory space occupied by the picture

Large graph loading first to understand the quality of the picture and the calculation rules of the occupied memory: Bitmap.config

Bitmap.config

Introduction (the composition of each pixel point)

Space occupied by 1pix

1byte = 8 bit

1024*1024 picture size

Resolution

Alpha_8

Only the transparency, no color, then one pixel occupies 8 bits.

1byte

1M

R G B _565

That is r=5,g=6,b=5, there is no transparency, then one pixel occupies the 5+6+5=16 bit.

2byte

2M

ARGB_8888

Consists of 4 8-bit, that is, a=8,r=8,g=8,b=8, then one pixel occupies 8+8+8+8=32 bit.

4byte

4M

ARGB_4444

Consists of 4 4-bit, that is, a=4,r=4,g=4,b=4, then one pixel occupies 4+4+4+4=16 bit.

2byte

2M


Iii. Common strategies for loading and displaying1. Load directly and display: direct image decoding and display loading on the control, the common Setimageresource method is to directly load the image to the top of ImageView display, this method is the way to load the original; 2. Load into memory to do scaling: decode to memory or bitmap, determine whether the size of the bitmap need two times, zoom to the specified size and then display; 3. Reduce mass loading:

Decoding the time set Bitmap.inpreferredconfig, try to load different quality bitmap to memory;

4. Pre-load mode:

is to get the size of the image that will be loaded, the estimated memory consumption and whether we need such a resolution picture.

loading optimization of large graphs

With bitmapfactory loading picture, it provides Decoderesource and decodefile two ways to decode the resource directory and the local SDcard directory under the image, Provides a powerful bitmapfactory.options that gives me the configuration in the process of decoding pictures.

1. Load the picture below drawable using the Decoderesource method

The image resolution is: 8176 x 2368 The color model is: ARGB_8888, The resources required to fully load into memory are: around 73.6M, meaning that a large majority of Android phones will instantly leak memory.

When loading a picture, get the size of the picture and the format of the picture: set Injustdecodebounds to True, do not decode the image to memory, read only the basic information of the picture.

Bitmapfactory.options Options = new Bitmapfactory.options (); options.injustdecodebounds = true; Bitmapfactory.decoderesource (Getresources (), r.id.myimage, options); int imageheight = Options.outheight;int ImageWidth = Options.outwidth; String imageType = Options.outmimetype;

At this point, you can get the size and format of the picture, and then calculate the size of the occupied memory space according to the model you want to load:

/** * A helper function to return the byte usage per pixel of A bitmap based in its configuration. */public static int getbytesperpixel (Bitmap.config config) {    if (config = = Bitmap.Config.ARGB_8888) {        return 4;< c2/>} else if (config = = Bitmap.Config.RGB_565) {        return 2;    } else if (config = = Bitmap.Config.ARGB_4444) {        re Turn 2;    } else if (config = = Bitmap.Config.ALPHA_8) {        return 1;    }    return 1;}

Get The picture size according to the width and height of the picture:

/** * Get the image size in the RAM * * @param imagew * @param imageh * @return */public static long getbitmapsizeinmemory (int imagew, int imageh) {    return Imageh * Imagew * getbytesperpixel (Bitmap.Config.ARGB_8888);}

At this point, you can add some strategies, such as loading only the control size of the picture, or to determine the current memory usage, as appropriate load the picture: This time to set the Injustdecodebounds to False, Here we demonstrate how to load a picture at a specified resolution:

/** * Load Bitmap from Resources * * @param res resource * @param drawableid resource Image ID * @param imgh Destination Image Height * @param imgw destination Image width * @return */public static Bitmap LOADHUGEBITMAPFROMDR    Awable (resources resources, int drawableid, int imgh, int imgw) {log.d (TAG, "IMGH:" + imgh + "IMGW:" + IMGW);    Bitmapfactory.options Options = new Bitmapfactory.options ();    Preload set Injustdecodebounds True, this would load bitmap into memory Options.injustdecodebounds = true;    Options.inpreferredconfig = Bitmap.config.argb_8888;//default is Bitmap.Config.ARGB_8888    Bitmapfactory.decoderesource (Resources, Drawableid, options);    Get the image information Include:height and width int height = options.outheight;    int width = options.outwidth;    String mimeType = Options.outmimetype;    LOG.D (TAG, "width:" + width + "Height:" + height + "MimeType:" + mimeType); Get sample size int samplesize = GetscaleinsamplEsize (width, height, IMGW, IMGH);    Options.insamplesize = samplesize;    Decode bitmap with insamplesize set options.injustdecodebounds = false;    LOG.D (TAG, "Memory size:" + getbitmapsizeinmemory (width/samplesize, height/samplesize));    Bitmap Bitmap = bitmapfactory.decoderesource (resources, Drawableid, options); LOG.D (TAG, "w=" + bitmap.getwidth () + "h=" + bitmap.getheight () + "Bitmap size:" + bitmap.getrowbytes () * Bitmap.getheig    HT ()); return bitmap;}


2. Load the picture below SDcard using the DecodeFile method Picture information Ibid.

/** * Load the bitmap from SDcard with the IMGW and IMGH * * @param imgpath Resource path * @param imgh result image  Height * @param IMGW result image width * @return result bitmap */public static bitmap Loadhugebitmapfromsdcard (String    Imgpath, int imgh, int imgw) {log.d (TAG, "IMGH:" + imgh + "IMGW:" + IMGW);    Bitmapfactory.options Options = new Bitmapfactory.options ();    Preload set Injustdecodebounds True, this would load bitmap into memory Options.injustdecodebounds = true; Options.inpreferredconfig = Bitmap.config.argb_8888;//default is Bitmap.Config.ARGB_8888 bitmapfactory.decodefile    (Imgpath, options);    Get the image information Include:height and width int height = options.outheight;    int width = options.outwidth;    String mimeType = Options.outmimetype;    LOG.D (TAG, "width:" + width + "Height:" + height + "MimeType:" + mimeType);    Get sample size int samplesize = getscaleinsamplesize (width, height, IMGW, IMGH); Options.insamplEsize = samplesize;    Decode bitmap with insamplesize set options.injustdecodebounds = false;    LOG.D (TAG, "Memory size:" + getbitmapsizeinmemory (width/samplesize, height/samplesize));    Bitmap Bitmap = Bitmapfactory.decodefile (Imgpath, Options); LOG.D (TAG, "w=" + bitmap.getwidth () + "h=" + bitmap.getheight () + "Bitmap size:" + bitmap.getrowbytes () * Bitmap.getheig    HT ()); return bitmap;}

The principle of the two approaches is exactly the same.

3. The method of calculation and the point of attention of Insamplesize

According to the official documentation we can see that the insamplesize must be 2 of the number of times, if not 2 of the number of times will automatically transpose the number of the 2 index times, below I provide a calculation method:

/**     * Get the scale sample size     *     * @param resW resource Width     * @param resh Resource Height     * @param DESW result width     * @param desh Result height     * @return     *    /public static int getscaleinsamplesize (int res W, int resh, int desw, int desh) {        int scalew = RESW/DESW;        int Scaleh = Resh/desh;        int largescale = Scaleh > Scalew? Scaleh:scalew;        int samplesize = 1;        while (SampleSize < largescale) {            samplesize *= 2;        }        LOG.D (TAG, "samplesize:" + samplesize);        return samplesize;    }

Next, I will continue to explain: Picture loading image caching and asynchronous loading technology.



finally I enclose the project's GitHub address:https://github.com/CJstar/HugeLocalImageLoad.git


Reference: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android big picture load Memory optimizer (how to prevent outofmemory)

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.