android - viewPager滑動(dòng)瀏覽一組大圖,滑動(dòng)倒數(shù)第二張時(shí)請(qǐng)求新數(shù)據(jù)追加數(shù)據(jù)……
問(wèn)題描述
在listView中點(diǎn)擊例如“美女圖片”后打開(kāi)一個(gè)largeActivity;
largeActivity中有一個(gè)viewPager實(shí)現(xiàn)左右滑動(dòng)瀏覽大圖;
在largeActivity打開(kāi)的時(shí)候會(huì)通過(guò)okHttp從服務(wù)器請(qǐng)求一組5張圖片鏈接,圖片通過(guò)glide加載在viewPager中實(shí)現(xiàn)左右滑動(dòng)瀏覽;
因?yàn)槊看尉W(wǎng)絡(luò)請(qǐng)求只能返回5張圖片鏈接,所以我在監(jiān)聽(tīng)每次滑動(dòng)viewPager的時(shí)候判斷當(dāng)前 postion小于存儲(chǔ)圖片鏈接的imageList.size() -1的時(shí)候,也就是每次滑動(dòng)到倒數(shù)第二張的時(shí)候去網(wǎng)絡(luò)請(qǐng)求下一組圖片的鏈接;
然后通過(guò)add將新請(qǐng)求到的圖片鏈接添加進(jìn)imageList,然后再執(zhí)行一次pagerAdapter.notifyDataSetChanged()來(lái)實(shí)現(xiàn)viewPager繼續(xù)滑動(dòng)瀏覽新請(qǐng)求到的圖片。
現(xiàn)在問(wèn)題是如果用戶以正常速度滑動(dòng)viewPager來(lái)瀏覽每張圖片的時(shí)候是沒(méi)有任何問(wèn)題的,但是如果用戶飛速滑動(dòng)viewPager的進(jìn)行瀏覽的時(shí)候就會(huì)出現(xiàn)在某一次請(qǐng)求新數(shù)據(jù)后就會(huì)出現(xiàn)APP崩潰的情況;錯(cuò)誤信息在兩部不同的手機(jī)上報(bào)錯(cuò)不一樣,但是都是在相同的情況下崩潰。Google遍都沒(méi)有找到解決辦法
華為榮耀報(bào)錯(cuò)如下:
通過(guò)華為手機(jī)的報(bào)錯(cuò)在網(wǎng)上找到通過(guò)設(shè)置 android:hardwareAccelerated='false'來(lái)關(guān)閉硬件加速的辦法,但是通過(guò)測(cè)試在快速滑動(dòng)時(shí)還是會(huì)導(dǎo)致APP崩潰自動(dòng)重啟的情況
樂(lè)視max2報(bào)錯(cuò)如下:
03-21 05:42:44.071 18730-18730/com.abcd.reader.abcdreader E/InputEventReceiver: Exception dispatching input event.03-21 05:42:44.071 18730-18730/com.abcd.reader.abcdreader E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback03-21 05:42:44.084 18730-18730/com.abcd.reader.abcdreader E/MessageQueue-JNI: java.lang.IllegalStateException: The application’s PagerAdapter changed the adapter’s contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 25, found: 30 Pager id: com.abcd.reader.abcdreader:id/vp_pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.abcd.reader.abcdreader.adapter.FollowDetailViewPagerAdapter
通過(guò)樂(lè)視手機(jī)的報(bào)錯(cuò)懷疑是當(dāng)新請(qǐng)求的數(shù)據(jù)add進(jìn)imageList后,但是還沒(méi)來(lái)得及執(zhí)行notifyDataSetChanged,剛好在這時(shí)用戶在滑動(dòng)viewPager的時(shí)候?qū)е碌模?b>為了驗(yàn)證猜測(cè)我修改了在當(dāng)前 postion小于存儲(chǔ)圖片鏈接的imageList.size() -2的時(shí)候,也就是每次滑動(dòng)到倒數(shù)第三張的時(shí)候去網(wǎng)絡(luò)請(qǐng)求下一組圖片的鏈接;給imageList.add和notifyDataSetChanged預(yù)留了充分的執(zhí)行時(shí)間,這時(shí)候再次測(cè)試問(wèn)題消失,華為手機(jī)和樂(lè)視手機(jī)均沒(méi)有再出現(xiàn)APP崩潰重啟的情況
但是我這個(gè)服務(wù)器請(qǐng)求回來(lái)的數(shù)據(jù)是不固定的,有時(shí)候可能每次返回5條,有時(shí)候10條,有時(shí)候只有1條,所以我現(xiàn)在的解決辦法并不能徹底解決煩請(qǐng)老師們給予指點(diǎn)一二,萬(wàn)分感謝!
問(wèn)題解答
回答1:大膽估計(jì)一下應(yīng)該是線程安全問(wèn)題,可以嘗試一下以下修改,獲取新數(shù)據(jù)時(shí),使用post方法去做更新,即viewPager.post(),notifyDataSetChanged放到post任務(wù)里去。還沒(méi)親自驗(yàn)證,如果不可以,也麻煩你告訴我一聲,我再看看。
回答2:具體錯(cuò)誤原因我暫時(shí)無(wú)法幫你定位,我給你另一個(gè)實(shí)現(xiàn)的思路,可以嘗試使用RecycleView來(lái)實(shí)現(xiàn)同樣的效果。
回答3:不知道是不是我理解錯(cuò)了,但images.size()-1不是倒數(shù)第二張,而是最后一張
建議把從服務(wù)器拉取條目的邏輯寫(xiě)到Adapter的getItem;
@Overridepublic Fragment getItem(int position) { if(getCount()-1 == position){//在此處拉取 } return ArrayListFragment.newInstance(position);}回答4:
策略就錯(cuò)了,每次只返回5個(gè)image的url是為什么?難道是為了節(jié)省流量嗎?最大的浪費(fèi)是三次握手的創(chuàng)建過(guò)程,上來(lái)就應(yīng)該拿到所有的url,然后自己控制圖片緩存。你每次到倒數(shù)第二張?jiān)偃フ?qǐng)求,也不怕麻煩.....
回答5:看問(wèn)題,題主是在viewpager滑動(dòng)監(jiān)聽(tīng)的方法里面做網(wǎng)絡(luò)請(qǐng)求,如果使用者快速左右滑動(dòng)viewpager,很可能多次執(zhí)行該回調(diào)。而之前的網(wǎng)絡(luò)請(qǐng)求還在進(jìn)行中,再次請(qǐng)求也就崩潰了。如果是這個(gè)原因造成的話,你可以增加一個(gè)標(biāo)記,如果當(dāng)前請(qǐng)求正在進(jìn)行中,在沒(méi)有得到正確或錯(cuò)誤的回調(diào)前,不再進(jìn)行新的網(wǎng)絡(luò)請(qǐng)求。至于返回不條目數(shù)不固定的問(wèn)題,如果你請(qǐng)求5張圖片,服務(wù)器只返回3張,說(shuō)明服務(wù)器圖片已經(jīng)全給你了,你的網(wǎng)絡(luò)請(qǐng)求也就不要執(zhí)行了
