Android解決ListView加載圖片閃爍
最近負責帶領公司項目重構,重構的時候發現項目里面同時在使用兩個圖片加載框架,andriod-universal-image-loader和fresco,這兩個框架其實都挺好的,不過項目里面不能同時使用兩個框架。因為他們初始化和運行的時候都需要分配一定的內存,這樣會導致緩存圖片的內存變大,如果不知情分配過大,還有可能導致隱形的oom。
問了以前的老員工都說不知道具體原因,說是歷史遺留問題。
***一個老員工說,一個類似發朋友圈功能的地方,如果用戶選擇了多張圖片待發送,這個時候用戶又點擊刪除某張圖片,這個時候剩下的圖片列表就會出現閃爍問題,說用fresco解決不了,用imageloader就不會出現閃爍的問題。暈,總不能因為要解決一個問題引入一個700kb的第三方框架吧!
fresco是facebook出品,在穩定性和調用簡易性方面還是值得信賴的。andriod-universal-image-loader比較大,并且好像很長時間也不怎么維護和更新了。***決定使用fresco框架。
使用fresco那么就面對自己解決加載圖片閃爍的問題,其實所有圖片框架原理都大同小異,首先去memory里面加載,沒有找到就是去本地緩存sdcard里面查找加載,如果還沒有,那么沒辦法只能使用網絡從圖片服務器加載了。
回歸正題,導致刪除圖片閃躲的原因是什么呢?
刪除一張圖片后,需要對圖片列表進行刷新操作,這個時候需要重新從sdcard里面讀取圖片,這么問題就來了,因為現在的手機照相機像素都非常高,好多都是4000*2500的,你可以測試一下BitmapFactory.decodeFile()從sdcard加載一張這樣大小的圖片需要300多ms,如果加上旋轉變換,那么至少需要1500多ms。你想肯定會出現卡頓閃爍的問題了。
知道導致原因,那么如何解決?
- 必須對Bitmap做縮略圖處理。
- 對于已經加載過的進行memory緩存處理。廢話不多說,直接上代碼吧!
***步:創建一個hashmap保存bitmap對象,千萬記得bitmap要用弱引用,防止加載過多導致oom。
第二步:從map中直接取出bitmap,如果不為空就直接顯示,為空就從sdcard中加載。
第三步:記得開啟開啟多線程加載,本地看似挺快,圖片多了也會anr,也會卡頓。用戶體驗不好。
第四步:這里面有兩個比較關鍵的技術點。
1、加載bitmap的時候,對圖片進行壓縮。
2、對于三星手機拍照后圖片旋轉問題,如何對圖片進行旋轉處理。
以上就是解決問題的所有代碼,總共加起來不到100行,問題都解決了,最主要用這不到100行代碼,替換了一個700kb左右的圖片加載框架,這個才是解決問題的***收益。
現在的程序員有一個通病就是都是喜歡拿來主義,啥都喜歡用第三方的,別人現成的,導致現在好多公司的項目引入大量的第三方庫,有很多僅僅用了不到千分之一的功能,你說何必呢?自己分析下,幾行代碼往往就可以解決了。
***送給所有的it朋友一句話,希望引起你們的共勉。
- 所有復雜問題要簡單化,所有簡單問題還是要簡單化。