Android OOM問題終極解決方案

來源:互聯網
上載者:User

標籤:android   des   style   blog   color   使用   

     大家在安卓開發的過程中使用Bitmap,尤其是當程式中包含大量圖片的時候或多或少會遇到OOM(Bitmap: Out Of Memory),遇到這個問題是非常痛苦的,在這裡給大家分享一下我自己結合網路上尋找的各種方案,以及自己的研究總結出來的解決方案。

     首先大家要知道OOM為什麼會出現,通過上網查資料明白了是由於使用了 BitmapFactory.decodeFile(filePath) 這個方法導致的,這個方法通過Google提供的sdk看代碼是將整個檔案直接讀取的所以佔用資源比較大,所以找到的所有的解決方案一般都是直接調用BitmapFactory的底層decode方法,代碼如下:

BitmapFactory.Options opt = new BitmapFactory.Options();opt.inPreferredConfig = Bitmap.Config.ARGB_8888;        //  A  R  G  B        //透明度 紅色 綠色 藍色        //Bitmap.Config ARGB_4444 16 每個像素 佔四位           //Bitmap.Config ARGB_8888 32 每個像素 佔八位          //Bitmap.Config RGB_565 16 R佔5位 G佔6位 B佔5位 沒有透明度(A)opt.inPurgeable = true;opt.inInputShareable = true;// 擷取資源圖片File imageFile = new File(filePath);FileInputStream fis = null;try{    fis = new FileInputStream(imageFile);}catch (FileNotFoundException e){    // TODO Auto-generated catch block    e.printStackTrace();}Bitmap bm = null;if (fis != null){    try    {        bm = BitmapFactory.decodeFileDescriptor(fis.getFD(), null, opt);    }    catch (IOException e1)    {        // TODO Auto-generated catch block        e1.printStackTrace();    }    finally    {        try        {            fis.close();        }        catch (IOException e)        {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

對於Bitmap.Config的選擇大家可以根據自己的實際情況進行選擇,我的程式中使用的是Bitmap.Config.ARGB_8888,雖然經過他的處理圖片佔用的記憶體相對而言小了不少,但是對比其他的方式來說這個參數佔用的記憶體也已經比較大了,但是為了保證圖片的品質還是選擇了它。

     上面的內容就是在我自己查資料的過程中找到的大部分的解決方式,在開發前期這種的確是夠用了,我也沒有意識到這樣處理會有什麼其他的隱患或者有什麼地方沒有處理正確,但是到了後期由於用戶端頁面層數較多,圖片也比較多這時候可惡的OOM又開始出現了,在節省記憶體方面實在找不到什麼更好的方式了,偶然發現了一個問題,我的Bitmap建立了,使用完之後並沒有將資源釋放掉,所以多個頁面的圖片都是一直佔用裝置記憶體的,不知不覺OOM就出現了。想解決這個問題看了幾個比較高深的文章,他們提倡用堆棧分配記憶體來解決這個問題,看了半天也沒有看明白,於是就使用了一個比較笨的方法,但是沒想到效果出奇的好,從那時開始OOM就徹底離我遠去了。我做的app由於頁面有一些相同的處理,所以有一個頁面的基類,使用最簡單的方式我在這個基類中添加了

/*** 存放Bitmap*/private List<Bitmap> bitmapList = new ArrayList<Bitmap>();

在我調用工具類的時候就將新擷取的Bitmap放到這對應的頁面中來,在上面方法上面就加了這一句話

if (bm != null){    activity.getBitmapList().add(bm);}

這樣我就能將所有的Bitmap通過我的頁面全部管理收集起來了,最後我選擇了在頁面銷毀的時候來將該頁面綁定的所有Bitmap未釋放的資源全部釋放

@Overrideprotected void onDestroy(){    for (Bitmap bitmap : this.getBitmapList())    {        if (!bitmap.isRecycled())        {            bitmap.recycle();        }    }    super.onDestroy();}

這樣就大功告成了!

     雖然我這個方法將所有頁面的Bitmap資源全部集中儲存起來耗費的記憶體還是比較大但是對於基本的來說這樣就夠用了,如果有圖片用到比較多的地方大家可以直接將定義個List轉換為Array,檢測數組滿時依次進行釋放替換。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.