Bitmap recycle()

from : http://blog.csdn.net/lavernock/article/details/5966517

Bitmap調用recycle? When?

 

 

Bitmap有一個recycle方法,意思很簡單,回收Bitmap的空間。

 

Q 1: Bitmap是否有調用recycle方法的必要性?

A: 嵌入式系統總是格外注重空間的問題,不小心的話就會有OOM。但是應用層使用java的android平臺有其天然的優勢【java語言有自己的垃圾回收,android平臺上各個application有自己的process自己的空間】。

    無需調用bitmap的理由有:

    a. 垃圾回收會處理的;

    b. 當application關閉,process被殺掉,所有這個process佔用的空間自然迴歸系統;

 

    但是,如果你有點潔癖,或者有點理想主義,或者很有控制慾,或者很閒。。。bitmap的recycle函數的調用還是可以是有必要的,理由有:

    a. 垃圾回收雖然好使,但是有可能的話,我們還是讓它少乾點活吧。垃圾回收有很大的未來不確定性,會加重未來未知時間點的loading,若有大量bitmap需要垃圾回收處理,那必然垃圾回收需要做的次數就更多也發生地更頻繁,小心會造成ANR。但是,若是自己recycle,就可以可控制地分散處理了這些回收任務了。

    b. 若是launcher那樣一直運行的application,它的process一直存在,memory問題還是多多注意下比較好。

 

Q2: When?

A: Timing的問題在這裏很重要。早了就大事不好了,會有這樣的Exception:

    java.lang.RuntimeException,Canvas: trying to use a recycled bitmap

android.graphics.Bitmap@44ebeee0,Canvas.java,955

    So, 怎樣纔可以保證不會早了呢?

    關於圖片顯示,重要的時間點:

    step1: 設置進去的時間點;

    Step2: 畫面畫出來的時間點;

    最保險最笨的做法,在新的圖片設置進去以後再recycle掉老的圖片,這樣做的壞處在於,在某個時間段,你需要的空間是double的【新舊兩套都在】;

    如果你不偏向於那麼做,又有時間,可以考慮後面一個時間點,除了setImage以及其它代碼中顯示調用那個bitmap的時候我們會檢查bitmap,在acticvity變爲visible的時候系統還是會去找之前設置進去的bitmap【即使你的onResume方法裏面並沒有提到去refresh UI,這件事情它也是會去做的,大概不然它就不知道這次該顯示些什麼了】。所以,在UI線程裏面,在一個不可能被打斷的方法裏面,是先設置新的bitmap還是先recycle舊的圖片是沒有影響的。

    譬如說     mBitmap.recycle();

                  mBitmap = .....   //設置

                  mImageView.setImage(mBitmap);

    這樣的代碼是完全可以的。

 

    後面這樣的做法,最重要的就是確保:在UI線程【因爲設置UI顯示只能在UI主線程裏】裏面一個不可能被打斷的方法裏面。這個是爲了確保在兩者之間UI主線程不可能被打斷,不可能剛好從invisible變成visible。

    所以,特別小心兩種東西:

    1. 多線程【個人覺得最好不要在其他線程裏面調用UI用過的bitmap的recycle方法,多線程之間是很難保證時間順序的,暫時沒有想出一種在background thread裏面recycle的合理的方式】;

    2. 非及時發生的方法:譬如,發intent啊,發notify啊去通知UI主線程去做UI重新刷新並不能替代mImageView.setImage(mBitmap);這樣的句子。完全有可能,你確實發了intent出去了,但是目標activity之一還沒有做UI重新設置【Q: maybe沒收到 or 收到但還是等待處理,不確定這兩種可能是不是都有可能】,這個時候這個acitivity變成visible了,系統仍然試圖找舊的圖片,找不到了就會報exception了。

 

PS: java.lang.RuntimeException,Canvas: trying to use a recycled bitmapandroid.graphics.Bitmap@44ebeee0,Canvas.java,955 這樣的exception可能也許你並不能夠看到,默認的log裏面好像只能看到uncaught exception,第一次看到是在monkey的events.log裏面,若你知道怎麼打開相應手機這方面的log trace應該也是可以看到的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章