Android efficiently loads large charts and multi-graph solutions, effectively avoiding program OOM and androidoom
The following code shows the maximum memory available for each application.
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); Log.d("TAG", "Max memory is " + maxMemory + "KB");
The BitmapFactory class provides multiple parsing methods (decodeByteArray, decodeFile, decodeResource, etc.) for creating Bitmap objects. We should select an appropriate method based on the image source. For example, the decodeFile method can be used for images on the SD card, the decodeStream method can be used for images on the network, and the decodeResource method can be used for images in resource files.
These methods will try to allocate memory for the constructed bitmap, which will easily lead to OOM. Therefore, each parsing method provides an optional BitmapFactory. the Options parameter. If the inJustDecodeBounds attribute of this parameter is set to true, the resolution method cannot allocate memory to bitmap. The returned value is no longer a Bitmap object, but null. Although Bitmap is null, The outWidth, outHeight, and outMimeType attributes of BitmapFactory. Options are assigned values. This technique allows us to obtain the length and width of the image and the MIME type before loading the image, so as to compress the image as needed. The following code is used:
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;
How can we compress images?
You can set the value of inSampleSize in BitmapFactory. Options. For example, if we have a 2048*1536 pixel image and set the value of inSampleSize to 4, we can compress the image to 512*384 pixels. Originally, loading this image requires 13 MB of memory. After compression, only 0.75M is needed. (assume that the image is of the ARGB_8888 type, that is, each pixel occupies 4 bytes ). The following method calculates the appropriate inSampleSize value based on the input width and height:
Public static int calculateInSampleSize (BitmapFactory. options options, int reqWidth, int reqHeight) {// the height and width of the source image final int height = options. outHeight; final int width = options. outWidth; int inSampleSize = 1; if (height> reqHeight | width> reqWidth) {// calculate the final int heightRatio = Math. round (float) height/(float) reqHeight); final int widthRatio = Math. round (float) width/(fl Oat) reqWidth); // The minimum ratio of width to height is used as the value of inSampleSize. This ensures that the width and height of the final image must be greater than or equal to the width and height of the target. InSampleSize = heightRatio <widthRatio? HeightRatio: widthRatio;} return inSampleSize ;}
Image Cache Technology
The memory cache technology provides quick access to images that occupy a large amount of valuable memory of applications. The core class here is LruCache (which is provided in the android-support-v4 package ). This class is very suitable for caching images. Its main algorithm principle is to store recently used objects with strong references in javashashmap, in addition, the minimum recently used objects are removed from the memory before the cache value reaches the preset value.
In the past, we often used the implementation of a very popular memory cache technology, namely, SoftReference or WeakReference ). However, this method is no longer recommended, because from API Level 9, the garbage collector tends to recycle objects that hold soft or weak references, this makes soft references and weak references no longer reliable.
In API Level 11, image data is stored in the local memory, so it cannot be released in a foreseeable way, this poses a potential risk of application memory overflow and crash.