[TOC]
## 問題一:內存中如果加載一張 `500*500` 的 `png` 高清圖片.應該是占用多少的內存?
`Bitmap` 所占內存大小計算方式:圖片長度 x 圖片寬度 x 一個像素點占用的字節數
`png` 圖片應該有**alpha通道**,所以 `Bitmap.Config` 是 `ARGB_8888` 。4個8位一種占用32位。
500 * 500 * 4 = 1000000Bytes = 0.95MB
## 問題二:加載本地資源圖片,是否還是0.95MB呢?
先看一些基礎知識(后面有答案) [Android官網-提供備用位圖](https://developer.android.google.cn/training/multiscreen/screendensities#TaskProvideAltBmp) 這篇文章鏈接中的有講到:
> 要在像素密度不同的設備上提供良好的圖形質量,您應該以相應的分辨率在應用中提供每個位圖的多個版本(針對每個密度級別提供一個版本)。否則,Android 系統必須縮放位圖,使其在每個屏幕上占據相同的可見空間,從而導致縮放失真,如模糊。

例如,如果您有一個可繪制位圖資源,它在中密度屏幕上的大小為 48x48 像素,那么它在其他各種密度的屏幕上的大小應該為:
* 36x36 (0.75x) - 低密度 (ldpi)
* 48x48(1.0x 基準)- 中密度 (mdpi)
* 72x72 (1.5x) - 高密度 (hdpi)
* 96x96 (2.0x) - 超高密度 (xhdpi)
* 144x144 (3.0x) - 超超高密度 (xxhdpi)
* 192x192 (4.0x) - 超超超高密度 (xxxhdpi)
然后,將生成的圖片文件放在 `res/` 下的相應子目錄中,系統將根據運行應用的設備的像素密度自動選取正確的文件。之后,每當您引用`@drawable/xxx`時,系統都會根據屏幕的 `dpi` 選擇適當的位圖。如果您沒有為某個密度提供特定于密度的資源,那么系統會選取下一個最佳匹配項并對其進行縮放以適合屏幕。
實測:`1520 x 2688` 大小為 `334.28KB` 圖片,屏幕密度為480的手機;
- 放在 `drawable-xxdpi` 下加載到 `Bitmap` 中占用內存為 `16343040(1520*2688*4)`,因為圖片不需要進行縮放,所以只需要計算 `ARGB_8888` 占用的字節數就行;
- 放在 `drawable-mdpi` 下加載到 `Bitmap` 中占用內存為 `147087360(1520*3*2688*3*4)` ,因為 `mdip` 到 `xxdpi` 圖片的寬高分別會放大`3`倍;
[Bitmap壓縮章節-BitmapFactory.Options三件套](http://www.hmoore.net/book/stven_king/stven_king_android_interview_topic/preview/Bitmap/Bitmap%E5%8E%8B%E7%BC%A9.md) 中詳細講述了其原理。
`nodpi` 目錄中的資源被視為與密度無關,系統將不會對它們進行縮放。
*****
文章到這里就全部講述完啦,若有其他需要交流的可以留言哦~!~!
想閱讀作者的更多文章,可以查看我 [個人博客](http://dandanlove.com/) 和公共號:
- 寫在前面的話
- Java
- 基礎
- Double的比較
- 小數怎么用二進制表示
- 多線程
- 并發和并行
- 線程池
- 線程池背景
- 線程池構造
- 任務阻塞隊列
- Flutter
- 基礎知識
- Dart基礎
- Android
- 項目架構
- View
- 非UI線程更新View
- AlarmManager
- 對比postDelaryed和Timer
- Bitmap
- 加載100M的圖片卻不撐爆內存
- Bitmap壓縮
- Bitmap局部解碼
- 計算圖片的內存占用
- Android動畫
- Android動畫類型
- Android動畫原理
- 屬性動畫
- 幀動畫
- 補間動畫
- 使用動畫的注意事項
- Android新特性
- 權限組
- Android23(Marshmallow)-6.0
- Android24(Nougat)-7.0
- Android26(Oreo)-8.0
- Android28(Pie)-9.0
- Android29(Q)-10.0
- AndroidX遷移
- Kotlin
- 關鍵字
- Kotlin操作符
- CoroutineScope
- Flow
- CoroutineException