概括
上一篇文章提到進(jìn)行適配的時(shí)候,理想的情況是:針對不同密度的設(shè)備由設(shè)計(jì)提供不同的尺寸的圖片乏盐,分別放進(jìn)mipmap的不同文件夾下童谒,以實(shí)現(xiàn)基本一致的用戶體驗(yàn)乾翔。但是實(shí)際情況是多數(shù)公司都只會根據(jù)交互圖出一份切圖籽腕,我目前的項(xiàng)目也是這樣嗡呼。那么,此時(shí)問題就來了皇耗,圖片究竟該放在mipmap-mdpi南窗、mipmap-ndpi、mipmap-xndpi郎楼、mipmap-xxndpi万伤、mipmap-xxxndpi中的那個(gè)文件夾下呢?
之前我是直接把圖片放在mipmap-hdpi的文件夾下呜袁,不同的設(shè)備會自動(dòng)去到該文件夾下找相應(yīng)的圖片敌买,但是最近突然發(fā)現(xiàn)這樣做存在非常大的問題,因?yàn)椋?strong>相同的圖片放在不同的文件夾下在不同的設(shè)備上的內(nèi)存占用是不同的阶界。
具體我們來分析一下:
準(zhǔn)備的圖片參數(shù)為:1080*520px虹钮、32-bit color、文件大小373.32KB的圖片膘融,手機(jī)是魅藍(lán)note2芙粱,1920*1080px,尺寸為5.5英寸氧映,設(shè)備像素密度為3春畔。
主界面
public class MainActivity extends AppCompatActivity {
private ImageView imgView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgView = (ImageView) findViewById(R.id.img);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
printImgWH();
}
private void printImgWH(){
if (imgView==null){
return;
}
Drawable drawable = imgView.getDrawable();
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
System.out.println("img width:"+bitmap.getWidth()+";img height:"+bitmap.getHeight());
}
}
布局界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.zhl.mipmapdemo.MainActivity">
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_group_bg"/>
</LinearLayout>
代碼比較簡單。我們分以下的幾種情況進(jìn)行驗(yàn)證:
情況1.首先不設(shè)置圖片岛都,運(yùn)行app后內(nèi)存占用律姨、圖片寬高:
結(jié)果:app占用內(nèi)存為17.47M,空閑內(nèi)存為2.67M.圖片(bitmap)寬高輸出0*0px
情況2.把圖片放在mipmap-xxhdpi文件夾下臼疫,運(yùn)行app后內(nèi)存占用择份、圖片寬高:
結(jié)果:app占用內(nèi)存為19.61M,空閑內(nèi)存為0.52M.圖片(bitmap)寬高輸出1080*520px
情況3.把圖片放在mipmap-mdpi文件夾下烫堤,運(yùn)行app后內(nèi)存占用缓淹、圖片寬高:
結(jié)果:app占用內(nèi)存為36.43M,空閑內(nèi)存為3.71M.圖片(bitmap)寬高輸出3240*1560px
情況4.把圖片放在mipmap-hdpi塔逃、mipmap-xhdpi、mipmap-xxxhdpi文件夾下料仗,運(yùn)行app后內(nèi)存占用湾盗、圖片寬高:
這三種情況我就不放截圖了。結(jié)果分別是:
hdpi:app占用內(nèi)存為25.72M立轧,空閑內(nèi)存為3.71M.圖片寬高(bitmap)輸出2160*1040px
xhdpi:app占用內(nèi)存為21.96M格粪,空閑內(nèi)存為3.77M.圖片寬高(bitmap)輸出1620*780px
xxxhdpi:app占用內(nèi)存為18.68M躏吊,空閑內(nèi)存為1.45M.圖片寬高(bitmap)輸出810*390px
情況5.把圖片放在mipmap-xxhdpi文件夾下,同時(shí)設(shè)置ImageView的寬高分別為1dp帐萎,運(yùn)行app后內(nèi)存占用比伏、圖片寬高:
結(jié)果:app占用內(nèi)存為19.83M,空閑內(nèi)存為0.30M.圖片(bitmap)寬高輸出3240*1560px疆导,圖片(ImageView)的寬高輸出為3*3px
注:此種情況是后面加的赁项,因此與情況2的結(jié)果有差異,理想情況下app占用內(nèi)存和空閑內(nèi)存應(yīng)與情況2一致澈段。
結(jié)果分析:
1悠菜、在同一設(shè)備上,相同的圖片放在設(shè)備像素密度越高的文件夾下败富,圖片輸出的寬高越小悔醋。且根據(jù)像素密度的關(guān)系,呈現(xiàn)3:2:1.5:1:0.75的比例關(guān)系兽叮。
2芬骄、在同一設(shè)備上,相同的圖片放在設(shè)備像素密度越高的文件夾下鹦聪,圖片占用的內(nèi)存越小账阻。
3、圖片在硬盤上的大小椎麦,與之在內(nèi)存中的大小沒有直接關(guān)系宰僧。
4、相同像素密度的文件夾下观挎,圖片加載到內(nèi)存中bitmap的大小不受ImageView大小的影響琴儿,即圖片占用的內(nèi)存大小與圖片(ImageView)的實(shí)際大小無關(guān),只與圖片的分辨率有關(guān)嘁捷。
我們以xxhdpi設(shè)備上得到的數(shù)據(jù)進(jìn)行計(jì)算內(nèi)存占用:
1080*520*4*8/8 byte造成,即2246.4kb,即2.2464M.所以理論計(jì)算此時(shí)占用的內(nèi)容更應(yīng)該為初始內(nèi)存加此內(nèi)存雄嚣,即17.47+2.2464=19.7164晒屎,與實(shí)際值19.61基本一致(在誤差范圍內(nèi))。
Android中bitmap的默認(rèn)Config為:ARGB_8888缓升,此config表示每個(gè)像素分別由A鼓鲁、R、G港谊、B四個(gè)通道表示骇吭,每個(gè)通道占8bit,所以每一個(gè)像素的大小為4*8=32bit歧寺,即4kb燥狰。
另外棘脐,圖片在硬盤存儲時(shí)表現(xiàn)的大小,與內(nèi)存中表現(xiàn)不一致龙致≈欤看到另外一篇博文(結(jié)尾附上)解釋的很詳細(xì),是這樣寫的:
存放在硬盤上的圖片文件目代,會根據(jù)各自的壓縮規(guī)則進(jìn)行壓縮屈梁,比如Jpeg這種有損壓縮的圖片格式,最常使用可變字長編碼的哈弗曼編碼像啼,會使用哈弗曼樹俘闯,也就是最優(yōu)二叉樹,根據(jù)某些數(shù)據(jù)出現(xiàn)的頻率對數(shù)據(jù)段編碼忽冻,從而減少占用的硬盤大小真朗。
比如說“10111”這個(gè)序列在圖片的二進(jìn)制數(shù)據(jù)中出現(xiàn)的概率最大,那我們可以用“01”來代替這一段數(shù)據(jù)僧诚,原來5位的數(shù)據(jù)遮婶,用2位就可以表示了,這就是壓縮率60%湖笨。當(dāng)然這只是打個(gè)比方旗扑,在實(shí)際操作中需要考慮“異前綴原則”等編碼的基本原則。
而如果把圖像讀取到內(nèi)存中就不一樣了慈省,因?yàn)槲覀冃枰恳粋€(gè)像素都能在屏幕上顯示臀防,所以會把每個(gè)像素點(diǎn)都加載至內(nèi)存中,不會對相同像素進(jìn)行壓縮或者是替換边败,所以你也應(yīng)該能明白前面提到的Bitmap占用內(nèi)存大小的計(jì)算公式的由來了袱衷。
結(jié)論
<p>Android設(shè)備加載圖片時(shí),它會首先去到與該設(shè)備像素密度一致的文件夾下找圖片笑窜,如果找不到致燥,他會依次到其他文件夾下去找,但是最終的顯示結(jié)果會進(jìn)行縮放排截,規(guī)則是根據(jù)設(shè)備像素密度和對應(yīng)文件夾的像素密度的反比縮放圖片嫌蚤。即當(dāng)訪問的文件夾的代表像素密度更大時(shí),圖片表現(xiàn)出來的寬高會更小断傲,內(nèi)存占用也會更小脱吱。</p>
所以,當(dāng)我們只能為app提供一套切圖時(shí)认罩,優(yōu)先的考慮是盡可能的提供最高設(shè)備像素密度下的切圖箱蝠,并放在相應(yīng)的文件夾下,即xxxhdpi設(shè)備下的切圖,其次考慮提供主流像素密度設(shè)備的切圖抡锈,目前我項(xiàng)目中提供的均為1920*1080px,xxhdpi下的切圖乔外。這種切圖在xxxhdpi設(shè)備下會進(jìn)行一定的縮小顯示床三,需要注意最終呈現(xiàn)效果。
</br>
參考鏈接:
http://blog.csdn.net/zhaokaiqiang1992/article/details/49787117