1. 程式人生 > >關於Android中圖片大小、記憶體佔用與drawable資料夾關係的研究與分析

關於Android中圖片大小、記憶體佔用與drawable資料夾關係的研究與分析

研究內容

本篇內容主要探討以下場景:同一張圖片,放置在不同的drawable資料夾,在同一裝置上執行,對圖片大小及記憶體佔用有什麼影響。

研究方法

  • 控制變數法
  • 分析法

測試環境

採用錘子T1手機(1080*1960,xxhdpi)進行測試

對於記憶體的檢視,使用AS自帶的記憶體檢視工具。

圖片大小使用如下程式碼獲取

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">void</span> printBitmapSize(ImageView imageView) {
        Drawable drawable <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">=</span> imageView<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getDrawable();
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (drawable <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) {
            BitmapDrawable bitmapDrawable <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">=</span> (BitmapDrawable) drawable;
            Bitmap bitmap <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">=</span> bitmapDrawable<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getBitmap();
            <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">Log</span><span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>d(<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">TAG</span>, <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">" width = "</span> <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">+</span> bitmap<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getWidth() <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">+</span> <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">" height = "</span> <span class="hljs-subst" style="margin: 0px; padding: 0px; color: rgb(0, 0, 0); box-sizing: border-box;">+</span> bitmap<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getHeight());
        } <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">Log</span><span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.</span>d(<span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">TAG</span>, <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"Drawable is null !"</span>);
        }
    }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li></ul>

研究過程

下面將給出測試的過程的截圖,然後進行分析和總結

下面的測試使用的是一張720*1280解析度的png圖片,32位色,佔用硬碟大小為77.11k

下面給出測試工程程式碼,非常簡單

主介面

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">AppCompatActivity</span> {</span>

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String TAG = <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"MainActivity"</span>;

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> ImageView img;

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) {
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        img = (ImageView) findViewById(R.id.img);
    }

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">onWindowFocusChanged</span>(<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> hasFocus) {
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onWindowFocusChanged(hasFocus);
        printBitmapSize(img);
    }

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">printBitmapSize</span>(ImageView imageView) {
        Drawable drawable = imageView.getDrawable();
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (drawable != <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            Log.d(TAG, <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">" width = "</span> + bitmap.getWidth() + <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">" height = "</span> + bitmap.getHeight());
        } <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            Log.d(TAG, <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"Drawable is null !"</span>);
        }
    }

}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">27</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">28</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">29</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">30</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">31</li></ul>

佈局介面

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
    <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>></span>

    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">ImageView
</span>        <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/img"</span>
        <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
        <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span> /></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout</span>></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li></ul>

在不設定圖片的情況下,App佔用記憶體8.31M

以下為測試部分

把圖片放置在drawable資料夾下,圖片大小為2160 * 3840,記憶體佔用39.88M

把圖片放置在drawable-mdpi資料夾下,圖片大小為2160 * 3840,記憶體佔用39.84M

把圖片放置在drawable-hdpi資料夾下,圖片大小為1440 * 2560,記憶體佔用22.26M

把圖片放置在drawable-xhdpi資料夾下,圖片大小為1080 * 1920,記憶體佔用16.11M

把圖片放置在drawable-xxhdpi資料夾下,圖片大小為720 * 1280,記憶體佔用11.86M

把圖片放置在drawable-xxxhdpi資料夾下,圖片大小為540 * 960,記憶體佔用10.29M

結果分析

從上面的測試結果,我們可以得出如下結論:

  1. 同一張圖片,放在不同目錄下,會生成不同大小的Bitmap
  2. Bitmap的長度和寬度越大,佔用的記憶體就越大
  3. 圖片在硬碟上佔用的大小,與在記憶體中佔用的大小完全不一樣

下面我會對上面幾個問題一一解釋。

我們以放在drawable資料夾下面的圖片為例,載入到記憶體之後,2160*3840大小的Bitmap佔用的記憶體為

2160 * 3840 * 4 = 3317,7600 byte = 3,2400kb = 31.640625 M

所以drawable資料夾下的App記憶體佔用 = 原始記憶體8.31M+圖片記憶體31.64M= 39.95M ,與實際記憶體佔用39.88M存在0.1755%的誤差,在誤差範圍之內。

先簡單解釋一下上面的計算公式,長*寬是圖片的畫素總數,乘以4則是因為一個畫素佔用A、R、G、B四個通道,每個通道佔用8位,所以描述一個畫素需要32位即4個位元組。

一個顏色通道需要8位描述,2^8=256,所以每個顏色通道就有256種狀態。如果把彩色圖轉化成灰階圖的話,也有256種狀態分割從白色到黑色之間的過渡顏色。

當然,也並不是所有格式的圖片每個畫素佔用4位元組,這和圖片在載入時設定的Bitmap.Config有關,預設的是Bitmap.Config.ARGB_8888,其他型別如下:

  • Bitmap.Config.ALPHA_8 此時圖片只有alpha值,沒有RGB值, 
    一1個畫素佔用一個位元組
  • Bitmap.Config.ARGB_4444 一個畫素佔用2個位元組,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各佔4個bites共16bites,即2個位元組
  • Bitmap.Config.ARGB_8888 一個畫素佔用4個位元組,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各佔8個bites,共32bites,即4個位元組。這是一種高質量的圖片格式,在電腦上普通採用。它也是Android手機上一個Bitmap的預設格式。
  • Bitmap.Config.RGB_565 一個畫素佔用2個位元組,沒有alpha(A)值,即不支援透明和半透明,Red(R)值佔5個bites ,Green(G)值佔6個bites ,Blue(B)值佔5個bites,共16bites,即2個位元組。對於沒有透明和半透明顏色的圖片來說,該格式的圖片能夠達到比較的呈現效果,相對於ARGB_8888來說也能減少一半的記憶體開銷。因此它是一個不錯的選擇。

那麼為啥在硬碟上儲存只需要77.11k,放到記憶體裡面就需要30多M呢?

因為這根本不是一回事呀~

存放在硬碟上的圖片檔案,會根據各自的壓縮規則進行壓縮,比如Jpeg這種有失真壓縮的圖片格式,最常使用可變字長編碼的哈弗曼編碼,會使用哈弗曼樹,也就是最優二叉樹,根據某些資料出現的頻率對資料段編碼,從而減少佔用的硬碟大小。

比如說“10111”這個序列在圖片的二進位制資料中出現的概率最大,那我們可以用“01”來代替這一段資料,原來5位的資料,用2位就可以表示了,這就是壓縮率60%。當然這只是打個比方,在實際操作中需要考慮“異字首原則”等編碼的基本原則。

而如果把影象讀取到記憶體中就不一樣了,因為我們需要每一個畫素都能在螢幕上顯示,所以會把每個畫素點都載入至記憶體中,不會對相同畫素進行壓縮或者是替換,所以你也應該能明白前面提到的Bitmap佔用記憶體大小的計算公式的由來了。

說到這裡,其實後兩個結論已經解釋清楚了,那麼為什麼“同一張圖片,放在不同目錄下,會生成不同大小的Bitmap”呢?

如果你真的看懂了我之前寫的文章,那麼這個問題應該不算問題。

我的測試裝置為錘子T1,1080*1960,xxhdpi,所以說,如果把這張放置在xxhdpi的話,應該不會對影象進行放縮,也就是原始大小,所以我們在前面得到drawable-xxhdpi資料夾下,圖片大小為720 * 1280是完全可以理解的,就是圖片本身的大小。

當圖片放置在drawable-hdpi中時,圖片大小為1440 * 2560,長寬變為原來的兩倍,這是因為不同解析度之間的倍數關係導致的,來一張圖

我們可以很明顯的看到xxhdpi是hdpi的2倍,所以如果單獨放置在某個drawable資料夾,手機會自動根據當前的螢幕密度對圖片進行放縮。

比如上面,當把圖片放置在xxxhdpi裡面的時候,在xxhdpi的裝置上,圖片長 = 720 * (3/4) = 540,圖片寬 = 1280 * (3/4) = 960,這與上面的測試結果是完全一致的。

至於為什麼在前面的測試中,drawable和drawable-mdpi是一樣的大小,是因為drawable-mdpi是系統預設的畫素密度,其他畫素密度都以它為基數,當只在drawable中存在圖片時,如果使用該圖片,那麼將按照drawable-mdpi的放縮比例進行放縮。

結論

從上面的測試我們可以得出以下幾個結論:

  1. 當圖片放置在不同drawable資料夾中,且只有這一張圖片時,執行裝置會根據自身的螢幕密度,對圖片進行放縮,放縮比例符合前面圖上的規則
  2. 圖片檔案的大小與在記憶體中佔用的大小沒關係,記憶體中實際佔用大小與圖片解析度、畫素顯示引數有關

所以,在一個App裡面使用一套UI理論上應該是沒有問題的,但是要注意

  • 最好使用較高解析度的切圖,並且放置在正確的drawable資料夾中,比如按照xxhdpi的解析度進行切圖,放置在drawable-xxhdpi中
  • 對於可以使用.9格式的圖片,最好使用.9,減少資源大小
  • 如果有條件,最好提供多套UI切圖。如果只有一套切圖,系統需要對圖片進行壓縮,會進行大量運算,影響裝置效能。同時,在某些情況下,系統對圖片的壓縮會可能會出現鋸齒,造成資訊的丟失
  • 如果是多套切圖的話,最好不要直接用工具按照比例放縮,這樣小圖示會丟失一些細節。當然,這部分是美工來做的,可以讓她參考這篇文章利用PS CS6的新功能保持ICON細節飽滿完美

思考一下,如果把一個本來應該放在drawable-xxhdpi裡面的圖片放在了drawable資料夾中會出現什麼問題呢?

在xxhdpi裝置上,圖片會被放大3倍,圖片記憶體佔用就會變為原來的9倍!

另外一個難以解釋的問題

我還試著將上面那張圖片放置在drawable-xxhdpi資料夾下,觀察在不同螢幕密度裝置的表現

xxhdpi裝置(T1),圖片大小為720 * 1280,記憶體佔用 = 11.86M-8.31M= 3.55M

xxhdpi裝置(N5) ,圖片大小為720 * 1280,記憶體佔用 = 20.19M-16.82M = 3.37M

xxhdpi裝置(魅族m351),圖片大小為720 * 1280,記憶體佔用 = 20.17M-17.84M = 2.33M

xhdpi裝置(華為g716-l070) 記憶體佔用 = 7.72M-2.66M = 5.06M

hdpi裝置(聯想A360e),圖片大小為360 * 640,記憶體佔用 = 2.83M-2.96M = -0.7M

hdpi裝置(酷派7269),圖片大小為320 * 568,記憶體佔用 = 6.85M-2.78M = 4.07M

然後我就凌亂了,這是什麼玩意!除了俺的大錘子和原生的N5符合圖片記憶體計算公式,其他的裝置都是什麼玩意!聯想手機的還是負值!不過我在模擬機上測試得到的也是類似的效果,這個測試與上面的應該是同一種情況,具體原因不得而已。

有知曉原因的可以告訴我,謝謝。