編輯:Android開發教程
Android程序中一旦加載的圖片比較多,就有可能出現Out of Memory而導致程序崩潰。這個一方面是因為Android系統本身對於每個單獨的進程有內存大小的限制(有16M,64M,128M,256M等等),另一方面是因為Android系統對於圖片資源的垃圾回收比較慢(文章http://jiangnane.com/index.php/archives/230中對Android源碼進行了分析,發現Android的setImageViewBitmap(Bitmap bm)方法的源碼中沒有建立新的bitmap,而是用引用的方式來使用bm的,這就導致bm被多處引用)。
那一幅圖片占用的內存大概多大呢?這篇博文主要是記錄了我在測試一副圖片占用字節數時查閱的一些資料和測試結果。
Android的Bitmap.Config給出了bitmap的一個像素所對應的存儲方式,有RGB_565,ARGB_8888,ARGB_4444,ALPHA_8四種。RGB_565表示的是紅綠藍三色分別用5,6,5個比特來存儲,一個像素占用了5+6+5=16個比特。RGB_8888表示紅綠藍和半透明分別用8,8,8,8個比特來存儲,一個像素占用了8+8+8+8=32個比特。這樣的話如果圖片是以RGB_8888讀入的,那麼占用內存的大小將是RGB_565讀入方式的2倍。
通常我們給Imagview加載圖片是通過setDrawable或者在xml文件中用android:src來設置,從BitmapFactory.Options.inPreferredConfig的說明文檔可以看出,默認的加載圖片大小的方式是以RGB_8888讀入的。
API 12以上可以直接獲取,以下則是通過獲取高和行所占字節相乘得到的。
protected int sizeOf(Bitmap data) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) { return data.getRowBytes() * data.getHeight(); } else { return data.getByteCount(); } }
來源:http://stackoverflow.com/a/2408164/1767800
3.以RGB_565方式讀入圖片
public Bitmap readBitMap(Context context, int resId){ BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; //獲取資源圖片 InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is,null,opt); }
參考:http://blog.csdn.net/yangyangiud/article/details/12835885
4.獲取ImageView和其中drawable的大小
查看本欄目更多精彩內容:http://www.bianceng.cn/OS/extra/
獲取ImageView和其中drawable大小需要在onWindowFocusChanged獲取,在oncreate中返回的結果是0.
public void onWindowFocusChanged(boolean hasFocus){ ImageView imageView=(ImageView)findViewById(R.id.test1); Log.v("Testresult","width= "+imageView.getWidth()+" height= " +imageView.getHeight()); Log.v("Testresult","drawawidth= "+imageView.getDrawable().getBounds().width()+ " drawableheight= " +imageView.getDrawable().getBounds().height()); }
參考:http://stackoverflow.com/a/15128508/1767800
5.Oncreate()中的測試代碼
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView=(ImageView)findViewById(R.id.test1); Drawable drawable = imageView.getDrawable(); int bitmapWidth = drawable.getIntrinsicWidth(); //this is the bitmap's width int bitmapHeight = drawable.getIntrinsicHeight(); //this is the bitmap's height Log.v("Testresult","bitmapwidth= " +bitmapWidth+" bitmapHeight= "+bitmapHeight); Bitmap bitmap=((BitmapDrawable)imageView.getDrawable()).getBitmap(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) { Log.v("Testresult","bitmap bytes are"+bitmap.getRowBytes()*bitmap.getHeight()); } else { Log.v("Testresult", "bitmap bytes are"+bitmap.getByteCount()); } bitmap=readBitMap(this, R.drawable.pic_1000_562); //api 12之上可以直接獲取bitmap所占用的字節數 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) { Log.v("Testresult","bitmap bytes are"+bitmap.getRowBytes()*bitmap.getHeight()); } else { Log.v("Testresult", "bitmap bytes are"+bitmap.getByteCount()); } }
其中原圖片大小是1000*562,手機屏幕的分辨率是480*800.從圖中可以看出,采用android:src的加載方式占用的字節數是采用RGB_565加載方式的2倍。且1124000=2*1000*562字節。並且雖然在手機中顯示的時候bitmap被縮小顯示了,但是drawable的長寬所占字節是和圖片的尺寸相一致的。
在前面的例子中,我們忽略了一個重要的原則,在代碼和Layout中,直接使用了字符串常量,比如:<Button android:text=”Pattern
新浪微博有一部分json數據如下,你會發現這是個數組,但是數組沒有key,數組中的對象也沒有key。怎麼解析呢?fastjson遇到這種無名數組套無名對象也會報異常。所以
今天心血來潮,又把ADT升級了一下,升級到了ADT 22,悲催的發現項目用不了了(能編譯通過,運行出錯)。錯誤一:(警告)Unable to resolve superc
SimpleAdapter作為一個數據集,主要向ListView、GridView容器填充數據,總結了幾種填充方式,原理很簡單,直接看代碼 和效果圖1、 ListView