Вылетает на устройствах Motorola Android
В моем приложении я получаю сообщения о спорадических ошибках курсора, которые появляются только на телефонах Motorola. Я использую ListView, поддерживаемый запросом SQLite, для просмотра каталога, и запрос обновляется, когда каталог обновляется удаленно или локально.
Наиболее частые ошибки, которые мы видим:
- java.lang.IllegalStateException: это должно только быть вызвано, когда курсор действителен
- java.lang.IllegalStateException: курсор закрыт
- android.database.StaleDataException: доступ к закрытому курсору
- java.lang.IllegalStateException: попытка повторно открыть уже закрытый объект: android.database.CursorWindow
Это известная проблема, и есть ли исправление или обходной путь?
Я использую AsyncTask для обновления списка:
private class RefreshTask extends AsyncTask<Void, Void, Cursor> {
protected Cursor doInBackground(Void... params) {
return ReaderHelper.getItemCursor(getActivity(), ReaderHelper.itemFilter);
}
protected void onPostExecute(Cursor csr) {
int count = csr.getCount();
loadingBar.setVisibility(View.GONE);
if (count == 0) {
if (ReaderHelper.itemFilter.unread) emptyMessage.setText(getText(R.string.msg_no_item_unread));
else emptyMessage.setText(getText(R.string.msg_no_item));
}
mCursor = csr;
getActivity().startManagingCursor(mCursor);
mAdapter.changeCursor(mCursor);
}
}
Это адаптер.
private class ItemsAdapter extends ResourceCursorAdapter {
private ItemsAdapter(Context c, Cursor csr) {
super(c, R.layout.item_list_row, csr, false);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = super.newView(context, cursor, parent);
view.setTag(new ItemViewHolder());
return view;
}
@Override
public void bindView(View v, Context c, Cursor csr) {
...
}
}
1 ответ
По-прежнему недостаточно кода, чтобы читатели могли понять, что вы делаете, в частности, вы не показываете, как RefreshTask
создано. Но я замечаю, что RefreshTask
ссылается на Activity, предположительно, на Activity, которая его создала. Это может вызвать проблемы, если активность будет уничтожена во время RefreshTask
выполняется.
Вместо непосредственного обновления Activity, возможно, вам следует переопределить класс Application и поместить туда обновленное состояние. (См. Этот ответ для примера; этот ответ имеет другой пример, а также показывает обновления, необходимые для манифеста вашего приложения.)
Обратите внимание, что если вы идете по этому пути, вам не нужно, чтобы Activity управлял курсором. Вместо этого в onPostExecute вы можете сбросить данные курсора в массив, который хранится в объекте Application.