2013-07-09 2 views
1

Im сталкивается с проблемой в ОС Android v4.x (в частности, 4.0.3) с изменением данных ListView во время прокрутки - произошел сбой, говоря, что я пытаясь изменить данные не из основного потока пользовательского интерфейса, который не является истинным:Проблема с AOS 4.x и ListView - изменение данных во время прокрутки ListView

E/AndroidRuntime(2453): java.lang.IllegalStateException: 
The content of the adapter has changed but ListView did not receive a notification. 
Make sure the content of your adapter is not modified from a background thread, but only 
from the UI thread. [in ListView(16908298, class android.widget.ListView) with Adapter 
(class mypackage.activity.MyListViewActivity$ListViewAdapter)] 

Пользовательский интерфейс с ListView состоит из 2-х частей - самый большой из них является ListView и есть специальный контроль в нижней части, который вызывает данные для изменения, и это управление всегда видно. Таким образом, пользователь может запустить прокрутку ListView, и при прокрутке пользователь может использовать элемент управления, который запускает изменение данных ListView, и это приводит к сбою. Конечно, изменение данных происходит на резьбе mainUI и я использую notifyDataSetChanged():

monthChanger.setOnMonthChangedListener(new OnMonthChangedListener() { 

    @Override 
    public void monthDidChange(int month) { 
     currentMonth = month; 
     loadData(); 
     listAdapter.notifyDataSetChanged(); 
    } 

}); 

и LoadData() метод просто заполняет соответствующий ArrayList с другими данными:

void loadData() { 
     List<DataHolder> tempDataList = DataRetriever.getData(currentMonth); 
     dataList.clear(); 
     dataList.addAll(tempDataList); 
    } 

так здесь нет ничего особенного. Крушение не происходит с AOS 2.3.5. Другой способ получить тот же самый крах на AOS 4 - это нажать экран сразу после того, как данные были изменены, а ListView прокручивается вверх.
Что случилось и как избежать этой ошибки?

ответ

0

Единственный способ решения проблемы я нашел до сих пор, чтобы остановить список прокрутки, прежде чем изменять его данные:

// before changing the data of ListView's adapter 
if (listView!=null){ 
    MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0); 
    listView.dispatchTouchEvent(me); 
    me.recycle(); 
} 
// now its safe to change data and call notifyDatasetChanged()