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