Это Многопоточность Проблема и правильное использование Синхронизированные Блоки Это можно предотвратить.
Не добавляя лишних вещей в UI Thread и не вызывая потери отзывчивости приложения.
Я тоже сталкивался с тем же. И поскольку наиболее приемлемый ответ предлагает внести изменения в данные адаптера из потока пользовательского интерфейса, можно решить эту проблему. Это будет работать, но это быстрое и простое решение, но не лучшее.
Как вы можете видеть для нормального случая. Обновление адаптера данных из фонового потока и вызов notifyDataSetChanged в потоке пользовательского интерфейса работает.
Это незаконное исключение состояния возникает, когда поток пользовательского интерфейса обновляет представление, а другой фоновый поток снова изменяет данные. Этот момент вызывает эту проблему.
Так что если вы будете синхронизировать весь код, который изменяет данные адаптера и делает вызов notifydatasetchange. Эта проблема должна исчезнуть. Как у меня, и я все еще обновляю данные из фонового потока.
Вот мой конкретный код для других пользователей.
Мой загрузчик на главном экране загружает контакты телефонной книги в мои источники данных в фоновом режиме.
@Override
public Void loadInBackground() {
Log.v(TAG, "Init loadings contacts");
synchronized (SingleTonProvider.getInstance()) {
PhoneBookManager.preparePhoneBookContacts(getContext());
}
}
Этот PhoneBookManager.getPhoneBookContacts считывает контакты из телефонной книги и заполняет их в хэш-картах. Который непосредственно используется для списочных адаптеров для составления списка.
На моем экране есть кнопка. Это открывает деятельность, в которой перечислены эти номера телефонов.
Если я непосредственно установил Adapter над списком до того, как предыдущий поток завершит свою работу, это происходит быстрее, так как случай с навигатором случается реже. Появляется исключение. Это название этого ТАКОГО вопроса. Поэтому я должен сделать что-то подобное во втором упражнении.
Мой загрузчик во втором задании ожидает завершения первого потока. Пока это показывает индикатор выполнения. Проверьте loadInBackground обоих загрузчиков.
Затем он создает адаптер и доставляет его деятельности, где в потоке пользовательского интерфейса я вызываю setAdapter.
Это решило мою проблему.
Этот код только фрагмент. Вам нужно изменить его, чтобы он хорошо скомпилировался.
@Override
public Loader<PhoneBookContactAdapter> onCreateLoader(int arg0, Bundle arg1) {
return new PhoneBookContactLoader(this);
}
@Override
public void onLoadFinished(Loader<PhoneBookContactAdapter> arg0, PhoneBookContactAdapter arg1) {
contactList.setAdapter(adapter = arg1);
}
/*
* AsyncLoader to load phonebook and notify the list once done.
*/
private static class PhoneBookContactLoader extends AsyncTaskLoader<PhoneBookContactAdapter> {
private PhoneBookContactAdapter adapter;
public PhoneBookContactLoader(Context context) {
super(context);
}
@Override
public PhoneBookContactAdapter loadInBackground() {
synchronized (SingleTonProvider.getInstance()) {
return adapter = new PhoneBookContactAdapter(getContext());
}
}
}
Надеюсь, это поможет