Bitmap調用recycle? When?
?
?
Bitmap有一個recycle方法。含義很easy,恢復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 bitmap android.graphics.Bitmap@44ebeee0,Canvas.java,955 這種exception也許你可能無法看到,默認log這似乎僅能夠看到uncaught exception,我第一次看到monkey的events.log里面,如果你知道如何在這方面打開相應的電話log trace你也應該能看到。
?