Bitmap內(nèi)存占用優(yōu)化的關(guān)鍵:圖片分辨率、文件夾存放和加載策略
圖片內(nèi)存占用計算公式
- 圖片分辨率 = a*b 比如:180*120
- 圖片存放的文件夾對應(yīng)的dpi,比如hdpi是240,xhdpi是320dpi,我們定位為變量inDensity
- 手機設(shè)備的dpi,這個值取決于每臺手機,比如我的小米是440dpi (這個值并不是手機分辨率的平方之和 ,開根號,再除以手機尺寸,這個展示分辨率取決于廠商的算法), 我們定義為targetDensity
- 圖片縮放比例scale= targetDensity/inDensity,每個像素點的內(nèi)存大小pointMemory ,取決于色深,比如argb8888的色深就是32個bit位=4byte
- 圖片占用內(nèi)存=(圖片寬a*scale+0.5)*(圖片高b*scale+0.5)*pointMemory
同一張圖片,展示在不同分辨率手機上,內(nèi)存占用大小一致嗎?
不一致。因為inDensity的數(shù)值一致,但targetDensity的數(shù)值不一致,所以圖片的縮放比例不同,占用內(nèi)存自然不同.
同一手機設(shè)備加載不同分辨率文件夾下的同一圖片,內(nèi)存占用大小一致嗎?
一致。雖然不同分辨率下的inDensity數(shù)值是不同的,但只要設(shè)計師是按照規(guī)范切的圖,那么不同分辨率圖片之間的寬高縮放比例=inDensity之間的比例。 所以最終不同分辨率的圖片在同一設(shè)備上展示時,圖片寬高縮放后得到的最終值是一致的,內(nèi)存也就一致了。
ImageView控件的大小會影響內(nèi)存占用大小嗎?
不會。因為通過src屬性,我們在獲取對應(yīng)的drawable時,設(shè)置的density為0,density為0的情況下,圖片的寬高是不會進(jìn)行任何的縮放的,故而占用內(nèi)存大小也不會有任何的改變。 內(nèi)存占用大小=圖片原始寬*圖片原始高*色深
同一個資源id,通過BitmapFactory創(chuàng)建的bitmap和xml文件中ImageView設(shè)置的src,占用內(nèi)存是否一致?
會有不一致的場景。如果inDensity和targetDensity不一致,那么通過BitmapFactory創(chuàng)建的bitmap會進(jìn)行縮放,從而導(dǎo)致內(nèi)存大小!=圖片原始寬*圖片原始高*色深。而xml通過src屬性設(shè)置的圖片,因為density=0的原因,圖片不會進(jìn)行任何的縮放,內(nèi)存占用大小=圖片原始寬*圖片原始高*色深
三方圖片加載框架設(shè)置圖片大小,是否會影響圖片占用內(nèi)存?
會。三方框架設(shè)置圖片大小的操作本質(zhì),是修改圖片的寬高,圖片的寬高變了,占用內(nèi)存大小自然也就變了
Android圖片適配的規(guī)則
先找手機設(shè)備dpi對應(yīng)的drawable文件夾,如果當(dāng)前文件夾找不到,策略是優(yōu)先圖片縮小。 所以會接著去找高分辨率下文件夾有沒有這張圖片,高分辨率都沒有的情況下,會接著從低分辨文件夾中查找.
比如:手機設(shè)備dpi為320(xhdpi),如果在drawable-xhdpi文件中找不到對應(yīng)圖片,則接著去drawable-xxhdpi、drawable-xxxhdpi文件夾中查找,如果依然沒有找到,則去drawable-hdpi、drawable-mdpi下查找。
為什么建議圖片要放在正確的分辨率文件夾下?
只針對手機設(shè)備的分辨率是xxhdpi做分析,其余分辨率自行思考,targetDensity=480
分辨率是xxhdpi的圖片,放在正確的drawable-xxhdpi文件夾下。 inDensity=480,targetDensity=480,圖片縮放比例 scale=1
分辨率是xxhdpi的圖片,放在錯誤的drawable-xhdpi文件夾下。 inDensity=320,targetDensity=480,圖片縮放比例scale=1.5
內(nèi)存大小從width*height*pointMemeory變成了(width*1.5+0.5)*(height*1.5+0.5)*pointMemory,導(dǎo)致占用的內(nèi)存增加了許多。
一個dpi為320的手機設(shè)備,加載一張drawable-xxxhdpi下的圖片,占用的內(nèi)存和加載一張drawable-xhdpi下的圖片一樣嗎?
當(dāng)然一樣,加載高分辨率圖片時,圖片是會縮小的,圖片大小會縮放到和其他分辨率一致,故而占用內(nèi)存大小是一致的
既然我們手機加載不同分辨率目錄下的同一圖片,占用內(nèi)存大小都是一致的,那為什么還要創(chuàng)建多個drawable目錄呢?直接使用drawable-xxxhdpi,豈不是還可以縮小包體積?
這里涉及到一個問題,就是xml文件中我們使用ImageView控件,直接通過src屬性引用圖片資源的場景。
而通過xml文件引用圖片資源,占用的內(nèi)存大小如下: 因為通過src屬性,我們在獲取對應(yīng)的drawable時,設(shè)置的density為0,density為0的情況下,圖片的寬高是不會進(jìn)行任何的縮放的,故而占用內(nèi)存大小也不會有任何的改變。內(nèi)存占用大小=圖片原始寬*圖片原始高*色深
所以如果我是320的手機,我加載xhdpi下的圖片,假設(shè)圖片是18*12 argb8888,那內(nèi)存占用就是18*12*4,但如果我只在xxxhdpi下有圖片,假設(shè)圖片是36*24,那內(nèi)存占用就是36*24*4,內(nèi)存占用一下就翻了4倍。而我們drawable目錄下的圖片,幾乎都是用于xml引用圖片,很少會用bitmapFactory創(chuàng)建,所以還是每個文件夾下都放對應(yīng)分辨率的圖片是最好的。