溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ndroid bitmap out of memory總結(jié)、心得

發(fā)布時(shí)間:2020-08-16 17:29:30 來(lái)源:網(wǎng)絡(luò) 閱讀:458 作者:wo153 欄目:移動(dòng)開(kāi)發(fā)
  • setImageBitmap或setImageResource或BitmapFactory.decodeResource來(lái)設(shè)置一張大圖,這些函數(shù)在完成decode后,最終都是通過(guò)java層的createBitmap來(lái)完成的,需要消耗更多的內(nèi)存。

  • 改用先通過(guò)BitmapFactory.decodeStream方法,創(chuàng)建出一個(gè)bitmap,再將其設(shè)為ImageView的source

  • decodeStream最大的好處在于其直接調(diào)用JNI  的nativeDecodeAsset()來(lái)完成decode,無(wú)需再使用java層的createBitmap,從而節(jié)省了java層的空間

  • 如果在讀取時(shí)加上圖片的Config參數(shù),可以更有效減少加載的內(nèi)存,從而更有效避免out of memory的異常

  • 另外,decodeStream直接拿圖片來(lái)讀取字節(jié)碼,不會(huì)根據(jù)機(jī)器的各種分辨率來(lái)自動(dòng)適應(yīng),使用了decodeStream之后,需要配置相應(yīng)大小的圖片資源

  • 默認(rèn)情況下android進(jìn)程的內(nèi)存占用量為16M,因?yàn)閎itmap他除了java中持有數(shù)據(jù)外,底層C++的skia圖形庫(kù)還會(huì)持有一個(gè)SKBitmap對(duì)象,因此一般圖片占用內(nèi)存推薦大小應(yīng)該不超過(guò)8M


1、BitmapFactory.Options

  • inPreferredConfig 指定decode到內(nèi)存中,手機(jī)中所采用的編碼,可選值定義在Bitmap.Config中。缺省值是ARGB_8888??梢允笰LPHA_8、ARGB_444、ARGB_8888、RGB_565                                               bitmap占用內(nèi)存的算法如下:圖片的width*height*Config                                                                                                                                                                                                                                             如果config設(shè)置為ARGB_8888,那么上面的Config為4,也就是4個(gè)字節(jié)的意思。一張480*320的圖片占用的內(nèi)存就是480*320*4byte。 

  • inJustDecodeBounds 如果設(shè)置為true,并不會(huì)把圖像的數(shù)據(jù)完全解碼,亦即decodeXyz()返回值為null,但是Options的outAbc中解出了圖像的基本信息。

  • inSampleSize 設(shè)置decode時(shí)的縮放比例。

  • inPurgeable設(shè)為true的話表示使用BitmapFactory創(chuàng)建的Bitmap用于存儲(chǔ)Pixel的內(nèi)存空間在系統(tǒng)內(nèi)存不足時(shí)可以被回收,在應(yīng)用需要再次訪問(wèn)bitmap的Pixel時(shí),系統(tǒng)會(huì)再次條用BitmapFactory decoder重新生成Bitmap的Pixel數(shù)組,為了能夠重新解碼圖像,bitmap要能夠訪問(wèn)存儲(chǔ)bitmap的原始數(shù)據(jù)。在inPugeable為false時(shí)表示創(chuàng)建bitmap的pixel內(nèi)存空間不能被回收,這樣bitmapfactory在不停decodeByteArray創(chuàng)建新的Bitmap對(duì)象,不同設(shè)備的內(nèi)存不同,因此能夠同時(shí)創(chuàng)建的Bitmap個(gè)數(shù)可能有所不同,200個(gè)bitmap足以使大部分的設(shè)備出現(xiàn)OutOfMemory錯(cuò)誤。當(dāng)inPurgeable設(shè)為true時(shí),系統(tǒng)中內(nèi)存不足時(shí),可以回收部分bitmap占據(jù)的內(nèi)存空間,這時(shí)一般不會(huì)出現(xiàn)OutOfMemory錯(cuò)誤

  • inInputShareable是否深拷貝   




2、以最省內(nèi)存的方式讀取本地資源的圖片 

  1. BitmapFactory.Options opt = new BitmapFactory.Options();   

  2. opt.inPreferredConfig = Bitmap.Config.RGB_565;    

  3. opt.inPurgeable = true;   

  4. opt.inInputShareable = true;   

  5. //獲取資源圖片   

  6. InputStream is = context.getResources().openRawResource(resId);   

  7. BitmapFactory.decodeStream(is,null,opt);  


3、最近解決bitmap加載時(shí)out of memory的心得


游戲在加載背景圖片

       要么掛在BitmapFactory. decodeStream( assets .open(path));

    要么掛在surface = Bitmap.createBitmap (surface , 0, 0,
                surface .getWidth(), surface .getHeight(), matrix, true);

ndroid bitmap out of memory總結(jié)、心得第一次嘗試:看到圖片是png格式的,將圖片轉(zhuǎn)為jpg。圖片大小減少了不少。不過(guò)沒(méi)多大效果。  

        原因:雖然改為jpg,加載時(shí)存儲(chǔ)的方式會(huì)默認(rèn)為ARGB_565,本來(lái)是png為ARGB_8888,占用內(nèi)存會(huì)減少一半。不過(guò)開(kāi)銷還是很大,用createBitmap放大時(shí),改方法是java層的實(shí)現(xiàn),效率太差。

ndroid bitmap out of memory總結(jié)、心得第二次嘗試:想到cocos2d-x的瓦片地圖,所以將背景圖片分割為9份(自己用ps切),有些效果,不會(huì)每次切換場(chǎng)景都會(huì)掛,但是很多的征戰(zhàn)地圖,沒(méi)全部切,所以當(dāng)進(jìn)入沒(méi)切的場(chǎng)景時(shí),還是會(huì)掛。

                   原因:沒(méi)有找到問(wèn)題的源頭,變小圖了,加載時(shí)開(kāi)銷的內(nèi)存確實(shí)減少不少。不過(guò)太多場(chǎng)景都去切不太實(shí)際,這樣程序改變很大??赡軙?huì)出現(xiàn)bug的風(fēng)險(xiǎn)。

ndroid bitmap out of memory總結(jié)、心得第三次嘗試:配置BitmapFactory.Config的屬性,使用(2)中的方式讀取圖片,省去createBitmap去放大圖片,使用兩套資源,在這些屏幕上用大圖。成功解決問(wèn)題。

             原因:都用了BitmapFactory.decodeStream方法讀取圖片,改方法直接使用native方法,用c++實(shí)現(xiàn)。效率果然是高。雖然當(dāng)時(shí)還不知道這個(gè)原因。今天總結(jié)的時(shí)候通過(guò)源代碼才理解。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI