講個(gè)故事,那天發(fā)現(xiàn)一個(gè)問題,在segmentfault上搜到一個(gè)提問:
有沒有人用android做過類似的事情,其中一個(gè)activity里面一有一百多張圖片,如果反復(fù)進(jìn)入該activity就會(huì)導(dǎo)致溢出。
已經(jīng)測試過universal-imageloader,picasso、fresco工具,都不理想,或者是我使用方法的問題。求大神指點(diǎn)!!
我就提問給樓主:
兄弟我最近也遇到這個(gè)問題了,也是試過universal-imageloader,picasso,fresco,請(qǐng)問你是怎么解決的
樓主回:
android:largeHeap="true" .....這個(gè)問題的水很深,谷歌的解決方案都不會(huì)完全沒有內(nèi)存泄漏的問題。
剛開始時(shí)候我懷疑是系統(tǒng)的問題,然后網(wǎng)上開始搜,發(fā)現(xiàn)遇到這個(gè)問題的人并不多,我猜可能是因?yàn)樗麄儓D片加載比較少。樓主給的方案我早就知道了,一看就不行,只是分配的內(nèi)存多了一點(diǎn)而已。卻發(fā)現(xiàn)了內(nèi)存泄漏,然后懷疑是圖片緩存的問題,因?yàn)檫@幾個(gè)圖片加載工具都是支持圖片緩存的,于是開始搜imageloader內(nèi)存泄漏,發(fā)現(xiàn)了《使用AndroidStudio分析和解決ImageLoader引起內(nèi)存泄露問題》這篇文章。
我當(dāng)時(shí)以為我找到了答案,說的很有道理,也真的有用。就是把imageloader加載后生成的bitmap給手動(dòng)回收掉。
我當(dāng)時(shí)回樓主:
兄弟你悲觀了,我找到了一個(gè)好辦法,就是昨天晚上,universal-imageloader,picasso,包括Fresco,發(fā)現(xiàn)他們都是存在內(nèi)存泄漏,但是可以改,universal-imageloader改了以后就可以了,http://blog.csdn.net/editor19...,找了一個(gè)晚上找到的,可以用,其中會(huì)有小問題,根據(jù)下面的評(píng)論和回答就可以搞定
然后樓主把我的答案設(shè)置為最佳,但是我發(fā)現(xiàn)這個(gè)方法相當(dāng)于把圖片加載工具的優(yōu)點(diǎn)抹殺了,最騷的是
當(dāng)其他頁面嘗試使用imageloader加載同樣的圖片就會(huì)發(fā)生如下問題,而且并不好解決:
Canvas: trying to use a recycled bitmap android.graphics.Bitmap
我就自己去搞,最終找到一個(gè)方法,但是也開始懷疑其他問題,因?yàn)樵谡掖鸢傅臅r(shí)候搜到很多內(nèi)存泄漏的問題,而且圖片加載工具肯定很成熟的,怎么可能有這種問題,我就回了樓主:
*再告訴你我的解決方案吧,首先我們之前都是懷疑圖片工具的鍋,其實(shí)我懷疑可能不是,當(dāng)然我還沒有確定,等一下測一下,可能是我們自己的原因?qū)е碌膬?nèi)存泄露,導(dǎo)致那個(gè)我們重復(fù)進(jìn)去Activity沒有被回收,原因是里面一東西沒有回收,比如Context,或者Thread,我們用adpter時(shí)候最好傳getApplication進(jìn)去,因?yàn)槲乙恢痹趦?yōu)化,沒時(shí)間去確認(rèn)到底是哪里的問題,我現(xiàn)在解決方案,是那個(gè)要加載圖片的Activity,用ImageLoad來加載,退出的時(shí)候之前那個(gè)方法回收bitmap,這個(gè)Activity以外可能有和這個(gè)Activity重復(fù)的圖片,這樣如果外面再用IamageLoad加載圖片 ,你程序會(huì)崩掉,說你在使用一個(gè)已回收的bitmap,所以這時(shí)候,這個(gè)Activity以外有重復(fù)圖片的Activity,用Picasso或者其他圖片加載工具,這樣解決了。這個(gè)方法看起來不專業(yè),但能行。但是最重要的是可能我們兩個(gè)都傻逼了,可能是我們自己的問題導(dǎo)致Activity沒有被回收導(dǎo)致的內(nèi)存泄露,我等一下測一下。我前兩天被這個(gè)問題折磨,網(wǎng)上找了很久,自己也搞了很久才搞定,只是希望可以幫到更多的人
然后我開始去測試,去掉了之前那個(gè)手動(dòng)回收的方法,發(fā)現(xiàn)真的沒問題。搞了半天是因?yàn)樽约阂驗(yàn)榫€程里面?zhèn)魅肓水?dāng)前Activity的Context對(duì)象導(dǎo)致銷毀Activity的時(shí)候線程還沒有關(guān),那么將導(dǎo)致Activity的內(nèi)存資源無法回收,造成內(nèi)存泄漏。
所以說,大家都沒有問題那肯定是自己的問題,這么成熟的框架,不會(huì)犯這些錯(cuò)誤。我發(fā)現(xiàn)imageloader是可以自己回收內(nèi)存的,緩存達(dá)到一個(gè)值以后就釋放了之前的緩存了。
關(guān)于Context:
Context的生命周期是一個(gè)Activiy,而ApplicationContext的生命周期是整個(gè)程序。我們最要注意的就是Context的內(nèi)存泄露。在Activiy的UI中要使用Context,而在其他的地方比如數(shù)據(jù)庫、網(wǎng)絡(luò)、系統(tǒng)服務(wù)的需要頻繁調(diào)用Context的情況時(shí),要使用ApplicationContext,以防止內(nèi)存泄露。
Android內(nèi)存泄漏相關(guān)文章:http://www.itdecent.cn/p/c59c199ca9fa