非同步載入Listview The content of the adapter has changed but ListView did not receive a notification
阿新 • • 發佈:2019-02-01
錯誤
The content of the adapter has changed but ListView did not receive a notification
原因
在Android開發過程中,使用了大量的ListView,發現這個錯誤偶爾會出現。特別是做壓力測試的時候,不停的點選重新整理,更容易出現這個錯誤。程式碼中已經使用了Adapter的notifyDataSetChanged()方法通知UI更新了,但是還是會出現這個錯誤。究其根本原因,還是執行緒之間同步的問題。比如,執行緒1更新了Adapter中的內容,卻還沒有來得及通知內容已經更新,就又有執行緒2更新了Adapter中的內容,這個時候如果執行緒1再通知內容更新,就會出現上述異常了
解決方法
ListView的滾動有三種狀態第一是靜止狀態,SCROLL_STATE_IDLE
第二是手指滾動狀態,SCROLL_STATE_TOUCH_SCROLL
第三是手指不動了,但是螢幕還在滾動狀態。SCROLL_STATE_FLING
在靜止狀態 進行adapter 更新即可 示例程式碼如下:
class ListOnScrollListener implements AbsListView.OnScrollListener { private int visibleLastIndex; private LegworkAdapter adapter; private RTPullListView listView; private View footer; public ListOnScrollListener(LegworkAdapter adapter, RTPullListView listView, View footer) { this.adapter = adapter; this.listView = listView; this.footer = footer; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { visibleLastIndex = firstVisibleItem + visibleItemCount - 1; /* 如果滾動到最後一條 */ } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (adapter != null) { int itemsLastIndex = adapter.getCount(); // 資料集最後一項的索引 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && visibleLastIndex == itemsLastIndex) { //靜止狀態在進行adapter更新 否則異常退出 adapter.notifyDataSetChanged(); if (page < totalpage) { listView.addFooterView(footer); page = page + 1; flag = true; SharedPreferenceUtils sharedPreferenceUtils = new SharedPreferenceUtils(LegworkActivity.this); String subUrl = sharedPreferenceUtils.getString(SharedPreferEnum.SUB_URL.name()); int empId = sharedPreferenceUtils.getInt(SharedPreferEnum.EMP_ID.name()); new Task().execute(subUrl, String.valueOf(empId), String.valueOf(page), String.valueOf(Constant.PAGE_SIZE)); } } } } }