我們常常使用的drawable和mipmap到底區別在哪裡, 我們找到資料中關於它們的說明到底是不是符合我們實際的情況. ...
歡迎通過我的個人博客來查看此文章
老項目代碼中發現有的圖片放到了
drawable
中, 有的圖片放到了mipmap
中, 開發時秉承哪個目錄下文件多放哪裡的原則, 偶爾有疑惑搜一搜文章, 看到了結論也就這麼使用了, 不過今日有時間, 依次檢驗了一下文章中的內容, 發現和實際的表現出入甚遠.
常見的幾種結論
Case 1 drawable會剔除其它密度, mipmap會保留全部(實際上最終的結論和這個有關聯)
當xhdpi密度的手機在載入apk的時候Google是有一個優化的,是會剔除drawable其他密度的文件,只保留一個基本的drawable和drawable-xhdpi的文件,而mipmap是會全部保留的。
檢測方法也比較簡單, 在drawable
和mipmap
不同密度的問價夾下分別放入同一類圖片(圖片標文字用於檢查), 分別打包並檢查其大小
Case1.1 安裝包與應用大小
安裝包大小 | 應用大小 | |
---|---|---|
drawable | 13.3 MB (14,016,841 位元組) | 14.04MB |
mipmap | 13.3 MB (14,017,191 位元組) | 14.04MB |
結論1.1
由此可見, 雖然兩個安裝包大小略有差異, 考慮到圖片本身的大小(每張圖片都在1Mb作用), 可以認為放入drawable
和mipmap
文件夾中的圖片在安裝包和應用安裝後沒有差異
Case1.2 應用內表現
排除安裝包的情況, 我們看一下在應用內的表現情況(通過adb shell wm density保證只修改手機的dpi信息)
100 | 420 | 800 | |
---|---|---|---|
drawable | |||
mipmap |
結論1.2
由此可見, 文件不論放在哪個目錄下, 在手機中都會正確的顯示為其匹配的圖片資源
Case 1.3 應用內縮放
如果一個 imageView 有縮放動畫,使用 drawable 下的圖片,會一直使用一張來縮放圖片實現 imageView 縮放動畫。
如果使用 mipmap 下的圖片,會根據縮放程度自動選擇比當前解析度大而又最接近當前解析度的圖片來做縮放處理。
這個可能大家見得不是很多, 不過既然有這種說法, 那就來測試一下
drawable
小縮放比例 | 大縮放比例 |
---|---|
mipmap
小縮放比例 | 大縮放比例 |
---|---|
結論1.3
可以看到在縮放動畫的過程中, 一直顯示的都是同一個動畫
Case 2 應用內性能
Google對mipmap的圖片進行了性能優化, 使其可以表現的更好
drawable
性能檢查一覽 | MEMORY | 10次圖片載入平均時間 |
---|---|---|
146 |
mipmap
性能檢查一覽 | MEMORY | 10次圖片載入平均時間 |
---|---|---|
151 |
結論2
可以看到, 載入單張圖片的情況下其性能基本一致,不排除圖片太小/太少性能優化不明顯的情況, 不過嘗試單證圖片重覆載入的情況下依舊表現為性能相近的情況, 或許時只針對特殊類型有優化? 如各位知道的更詳細, 歡迎和我進行交流.
Case3 啟動圖標
在查閱資料的時候, 發現多次提及minmap應用只放入應用的啟動圖標, 使其可以得到優化.
100dpi | 420dpi | 800dpi | |
---|---|---|---|
結論3
可以看到, 不同dpi的情況下應用圖標的顯示情況都是一致的. 其應用圖標切換的邊界值也是一致的.
關於420dpi和800dpi顯示效果一樣的情況, 因為種種原因, 應用圖片在選擇圖片資源的時候, 需要將密度擴大25%左右[1].
看到這裡大家應該和我有著一樣的疑惑, 既然drawable和mipmap下圖片的表現不論是安裝包還是應用內, 甚至連官方文檔都這麼說了, 為什麼各種測試結果下來, 兩者的表現基本的一致呢?
罪魁禍首 Bundle(.aab)
提到Bundle(.aab)國內的開發者可能都比較陌生, 甚至不少之前做過Google Play上架應用的都不是很熟悉. 這個其實在我們每次手動打包的時候都會出現.
簡單來說.aab包一般用於Google Play商店使用, 在你從Google Play商店下載應用時, 它會根據你手機的實際使用情況來下載不同drawable中的資源. 以期望達到減少安裝包大小的目的. (一般情況下手機dpi不會改變, 其它密度下的資源文件直到應用卸載時都不會被使用).
下麵的測試使用到的工具為bundletool[2], 簡單來說, 就是模擬從Google Play下載應用和安裝應用的過程.
安裝包比較
安裝包(apks)大小 | 應用大小 | |
---|---|---|
drawable | 5.91 MB (6,201,543 位元組) | 6.22MB |
mipmap | 12.6 MB (13,230,670 位元組) | 13.26MB |
應用內表現
100 | 420 | |
---|---|---|
drawable | ||
mipmap | ||
可以看到, 當圖片放到drawable 相關文件夾下的時候, 通過.aab包安裝的應用會比放到minmap 的下的應用小許多, 並且應用內更改dpi的時候頁可以看到其不再能自動根據當前dpi選擇對應的圖片了. |
結論
那麼通過以上的測試, 我們可以得到以下結論了
以下結論均不涉及mipmap的性能優化相關(主要是暫未能設計好一個比較明確的測試對比)
以下測試機型為pixel 7, 測試Android版本為13
- 當應用構建為.apk的情況下,
drawable
和mipmap
文件夾下的資源表現無差異, 不論是應用內表現還是在啟動器(應用圖標)中表現. - 當應用構建為.aab的情況下,
drawable
文件夾下的資源會尋找匹配的設備密度保留, 不匹配的資源會被刪除已保證apk的大小.而mipmap
文件夾下的資源文件會全部被保留.
那麼我們應用內使用的圖片就可以放到任意的目錄下麽?
如果你的應用是通過.apk分發安裝的, 原則上是沒有區別的. 但是Google對相關的目錄也有推薦說明:
可以看到, mipmap
目錄下原則上只能保存應用圖標. 同樣, 其官方項目及單密度資源項目也都是這樣使用設計這兩個文件夾的.
.aab包內mipmap保留機制是否是只適用於應用圖標
測試後可以發現, mipmap的保留機制適用於mipmap下所有的圖片資源, 不論是否為應用圖標
相關代碼可以訪問我的GitHub