0 x00 preface
I just want to talk about the basic relationship between Bitmap and memory, but I find that if I really want to explain this seemingly simple thing, it is not so simple, don’t you believe it? Might as well try to answer the following questions first!
- Question 1: What is DPI? What is DP? A: Are you insulting me? I refuse to answer! Innocent face
- Question 2: take the Nexus6, for example. 1440 by 2560 resolution, 5.96 inches. What is ppi? What is dPI? How many pixels is 1DP?
- Q3: also take the Nexus6 as an example, a 180*180 image, placed in Settings
wrap_content
Property in ImageView when this image is placed separatelydrawable-nodpi
.drawable-mdpi
.drawable-hdpi
.drawable-xxhdpi
.drawable-xxxhdpi
What is the size of the image (pixel) displayed on the screen for each resource directory? - Q4: How much memory does this image take up?
- Question 5: If you set the width and height of the ImageView to fixed values, such as 50px, how much memory will be used by the loaded Bitmap?
This article mainly focuses on the above problems, introduces the basic mechanism of Android image resource loading, how to calculate the size of the image memory, and memory image analysis tools.
0x02 Basic Concepts
- Px: pixel, refers to the physical point on the screen, the smallest independent display unit
- Ppi: Pixels Per Inch. In my previous understanding, I use the Pythagorean theorem to calculate the length of the diagonal line based on the length and width of the screen, and then divide it by the screen diagonal inches.
- Dpi: What is the difference between Dots Per Inch and PPI?
- Dp: Density-Independent pixel, the dummy value defined by Android, and px
px = dp * (dpi / 160)
, why?
ppi
Ppi refers to the number of pixels per inch in either a horizontal or vertical direction, which is why a lot of understanding of PPI is problematic. Many articles use Pythagorean theorem to calculate the number of diagonal pixels on the phone screen!! However, the pixel distribution of the mobile phone screen is a dot matrix distribution. The diagonal pixel point of the dot matrix is not calculated by using the Pythagorean theorem, but is equal to the number of rows or columns. Why use the diagonal to calculate? Because the average cell phone size is measured in diagonal inches, not in length and width. Here is a formula derivation: let X/ X = Y/ Y = ppi, where X is the horizontal pixel value, X is the horizontal inch value, Y is the vertical pixel value, Y is the vertical inch value. (X²+Y²)/(X²+Y²) = (X/X) ²= (Y/ Y) ², which can be proved by Pythagorean theorem and similar triangle principle. Ppi is calculated in the same form as Pythagorean theorem but not the meaning of Pythagorean theorem, and the numerator is not the number of pixels on the diagonal!!
Conclusion: The formula for ppi can be expressed as square root (X²+Y²)/diagonal inches. **** does not mean that PPI is obtained by calculating diagonal pixel values using the Pythagorean theorem
What are the detailed calculation methods and algorithm sources of DPI, PPI, DP and PX? FSK answer
dpi
Dpi is determined by PPI, or Nexue6 is taken as an example. Ppi of Nexues6 can be calculated by using ppi calculation formula492
, refer to the table below, should be in the range of xxXHDPI, but its DPI is not492
. In fact, DPI only 120(low), 160(medium), 240(high), 260, 280, 300, 320(XHIGH), 340, 360, 400, 420, 480 (XXHPDI), 560, 640 (XXXHPI), you can refer toandroid.util.DisplayMetrics
The source code. throughgetResources().getDisplayMetrics().densityDpi
You can get the actual DPI of the phone.DisplayMetrics. Java source link
dp
How many pixels is 1DP on Nexues6? 1dp * (560/160) = 3.5px
How do I change the DPI of my mobile phone
- Root’s phone is required
- Change the ro.sf.lcd_density property in /system/build.prop. The smaller the value, the higher the screen density
- Adb reboot Restarts the phone
How to quickly check the screen information of mobile phone
adb shell dumpsys display | findstr DisplayDeviceInfo
0x03 Back to the question
Take Nexus6 as an example. A 180*180 image is placed in an ImageView with wrap_content set. When this image, Drawable -nodpi,drawable- MDpi,drawable-hdpi, drawable-xxhdpi,drawable-xxxhdpi,drawable-xxxhdpi,drawable-xxxhdpi,drawable-xxxhdpi,drawable-xxxhdpi
A: according to the above analysis, it can be seen that nexus6 is a screen belonging to xxxhpi, and the dpi obtained is 560. If you put a 180-size image in the xxxhdpi directory, will the screen display 180px? When loading an image, the Android system will scale the dPI of the current system and the source DPI of the image directory. If an image is placed in drawable-xxxhdpi, this tells the system that the image is just right for a phone screen with a dpi of 640, its scale is 1.0, and similarly, drawable-xxhpi corresponds to 480dpi. Drawable -xhdpi indicates 320dpi. If you want 180*180 to be the original size on the Nexues6 screen, you must place it in the drawable-nodpi or drawable-560dpi directory.
Int (180 * (560/240) +0.5f) = 420px, the actual image size should be 420px! Same with: in xhdPI directory, the actual size should be int (180 * (560/320) +0.5f) = 315px in xxhdPI directory, the actual size should be int (180 * (560/480) +0.5f) = 210px
Bitmapfactory.cpp source code link
If a small Bitmap is used and a larger Bitmap is placed, then the size of the Bitmap is calculated according to the size of the container. Or is it dPI scaling?
0x04 How much memory a picture takes up
Now we know how the size of a bitmap by system decode is calculated when an image is placed in different resource directories. How much memory does an image take up? How much memory does a pixel take up? We all know that the colors on the screen are represented by R, G, B and transparency. Android officially supports RGB formats such as ALPHA_8, RGB_565, ARGB_4444, and ARGB_8888.
For example, ARGB8888 represents a pixel, using 8 bits for transparency, 8 bits for Red, 8 bits for Green, and 8 bits for Blue. That adds up to 4 bytes per pixel, and RGB
565 pixels requires 2 bytes.
public enum Config { ALPHA_8 (1), RGB_565 (3), @Deprecated ARGB_4444 (4), ARGB_8888 (5); final int nativeInt; Config(int ni) { this.nativeInt = ni; }}Copy the code
If 180*180 is placed in the HDPI directory, the actual size should be int (180 * (560/240) +0.5f) = 420px. The pixel memory size is 420 * 420 * 4 = 705600byte = 689kb. In the same way: Int (180 * (560/320) +0.5f) = 315px; 315 * 315 * 4 = 396900Byte = 387.6 KB; The actual size should be int (180 * (560/480) +0.5f) = 210px, and the pixel memory size should be 210 * 210 * 4 = 176400Byte = 172.2KB
0x05 How do I analyze images in memory?
With all that said, here’s what I wanted to say. Android memory optimization needs to focus on several aspects, Bitmap loading, Activity leakage, WebView memory and so on. Image memory is the primary concern of many Android applications, especially e-commerce apps. How to simply analyze the situation of the memory Bitmap, here provides a tool. Leakcanary, by analyzing the memory heap dump fileandroid.graphics.Bitmap
Object case,Batch save Bitmap objects in memory to image filesIn this way, you can intuitively see the number, content and size of bitmaps loaded in memory, and then analyze possible memory problems.
The sample
Take the analysis of bitmap in Mogujie APP memory as an example:
- First, use Android Monitor to dump hprof
- Hprof-conv does format conversion
Java - jar. / bitmap - analyzer - 0.0.1 - the SNAPSHOT. Jar/Users/Ivonhoe hprof/com mogujie - conv. Hprof mushroom street
Parameter Description:
- Parameter 1: The absolute path to the hprof file that needs to be processed
- Parameter 2: The name of the folder for image output. This folder is created in the hprof file directory. By default, the output file is directly in the hprof file directory
The output shows that
- Size sort. TXT according to the image pixel size, from large to small sort
- Number sort. TXT according to the number of pictures of the same size, from large to small sort
- Filename width * height_index in PNG
The Jar package address
Raw.githubusercontent.com/Ivonhoe/mvn…
0x06 Reference Documents
Android Drawable microhacks, details of Drawable that you didn’t know about
This article is enough for Android adaptation
Export bitmaps in dump files in batches
Android development pitfall: How much memory do your Bitmaps take up?