Обновление базы данных SQLite в фоновом потоке на Android

Я использую пользовательский CursorAdapter для отображения данных, хранящихся в базе данных. Данные извлекаются с сервера, анализируются и вставляются в базу данных в отдельном потоке. Поскольку я не хочу хранить какие-либо старые данные, я удаляю все строки из таблицы, а затем вставляю каждую строку по мере анализа информации в ответе сервера. Если я прокручиваю ListActivity, я иногда получаю сбой, по-видимому, когда таблица очищается, а CursorAdapter getView или bindView пытаются запросить курсор.

Это НЕ мой пользовательский CursorAdapter, который терпит неудачу, я уже обработал исключение RuntimeException, которое может произойти, когда я использую getInt() или getString().

Из того, что я прочитал, сериализация запросов зависит от того, как вы используете SQLiteOpenHelpers. Я создал собственный SQLiteOpenHelper, похожий на пример блокнота в демоверсиях Android.

Когда я обновляю свою базу данных, я использую следующий фрагмент кода:

ContentResolver cr = ctx.getContentResolver();
ContentValues values = new ContentValues();
String response = _getUrlResponse(url);
cr.delete(tableName);
values.put(parseString(response));
cr.insert(tableName, values);

Есть ли лучший способ выполнения операций с базой данных, чем использование ContentResolver?

Логкат это:

03-07 15:35:07.351: ERROR/AndroidRuntime(15826): java.lang.IllegalStateException: couldn't move cursor to position 17
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.CursorAdapter.getView(CursorAdapter.java:178)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.AbsListView.obtainView(AbsListView.java:1460)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.ListView.makeAndAddView(ListView.java:1809)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.ListView.fillUp(ListView.java:764)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.ListView.fillGap(ListView.java:710)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3421)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:2301)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.widget.ListView.onTouchEvent(ListView.java:3621)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.view.View.dispatchTouchEvent(View.java:3823)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1723)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1129)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1707)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.os.Looper.loop(Looper.java:123)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at java.lang.reflect.Method.invokeNative(Native Method)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at java.lang.reflect.Method.invoke(Method.java:521)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-07 15:35:07.351: ERROR/AndroidRuntime(15826):     at dalvik.system.NativeStart.main(Native Method)

person JustinJ    schedule 07.03.2011    source источник
comment
в любом случае было бы неплохо опубликовать код курсора   -  person Matthew Willis    schedule 08.03.2011
comment
Я должен был сказать, что единственные функции CursorAdapter, которые я переопределяю, это newView() и bindView(). Что касается предложения getCount(), возможно, я могу сделать что-то вроде этого: @Override public View getView (int position, View convertView, ViewGroup parent) { try { return super.getView(position, convertView, parent); } catch (RuntimeException e) { e.printStackTrace(); super.getCursor().requery(); return newView(parent.getContext(), super.getCursor(), parent); } }   -  person JustinJ    schedule 08.03.2011


Ответы (2)


Возможно, вы не обновляете свое значение getCount() по мере изменения данных в вашем Cursor? Кажется, что он пытается перейти к строке, которой больше не существует.

person Matthew Willis    schedule 07.03.2011

У меня была аналогичная проблема. Я решил эту проблему, удалив строку, которая была в моем коде:

mCursorAdapter.notifyDataSetChanged();
person Anis Abboud    schedule 04.12.2014