Асинхронная задача, возвращающая данные после закрытия базы данных ORMLite от поворота экрана
Я получаю эту ошибку
10-11 13:58:46.713: E/AndroidRuntime(29407): FATAL EXCEPTION: AsyncTask #2
10-11 13:58:46.713: E/AndroidRuntime(29407): java.lang.RuntimeException: An error occured while executing doInBackground()
10-11 13:58:46.713: E/AndroidRuntime(29407): at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
10-11 13:58:46.713: E/AndroidRuntime(29407): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.lang.Thread.run(Thread.java:856)
10-11 13:58:46.713: E/AndroidRuntime(29407): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.philly.philly/databases/PhillyORM.db
10-11 13:58:46.713: E/AndroidRuntime(29407): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
10-11 13:58:46.713: E/AndroidRuntime(29407): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1310)
10-11 13:58:46.713: E/AndroidRuntime(29407): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.android.AndroidCompiledStatement.getCursor(AndroidCompiledStatement.java:154)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.android.AndroidCompiledStatement.runQuery(AndroidCompiledStatement.java:57)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.stmt.SelectIterator.<init>(SelectIterator.java:55)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.stmt.StatementExecutor.buildIterator(StatementExecutor.java:206)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.stmt.StatementExecutor.query(StatementExecutor.java:155)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.dao.BaseDaoImpl.query(BaseDaoImpl.java:261)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.stmt.QueryBuilder.query(QueryBuilder.java:262)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.stmt.Where.query(Where.java:482)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.j256.ormlite.dao.BaseDaoImpl.queryForEq(BaseDaoImpl.java:241)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.philly.philly.Repository.saveOrUpdateKontext(Repository.java:180)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.philly.philly.PostListActivity$LoadPostsTask.doInBackground(PostListActivity.java:161)
10-11 13:58:46.713: E/AndroidRuntime(29407): at com.philly.philly.PostListActivity$LoadPostsTask.doInBackground(PostListActivity.java:1)
10-11 13:58:46.713: E/AndroidRuntime(29407): at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-11 13:58:46.713: E/AndroidRuntime(29407): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
10-11 13:58:46.713: E/AndroidRuntime(29407): ... 5 more
Я считаю, что ключевой частью является 10-11 13:58:46.713: E/AndroidRuntime(29407): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.philly.philly/databases/PhillyORM.db
Это происходит, когда я поворачиваю экран, когда асинхронная задача получает данные с удаленного сервера.
Я предполагаю, что происходит то, что запрос возвращается и пытается записать в базу данных, но действие, которое запустило задачу, было уничтожено и перезапущено.
Если вам нужно увидеть мой код, я добавлю его, но я подумал, что источник этой проблемы может быть довольно понятен только из сообщений об ошибках и моего описания.
Я просто ищу, как правильно обрабатывать поворот экрана при извлечении удаленных данных и записи в локальную базу данных с использованием ORMLite. Может быть, я должен использовать службу вместо асинхронной задачи?
Заранее спасибо.
2 ответа
Ваша деятельность, вероятно, закрытие БД на ротации. Я предлагаю использовать AsyncTaskLoader, и он сам позаботится о ротации. http://developer.android.com/guide/components/loaders.html
Еще один совет, который я узнал из опыта, - иметь одноэлементный объект БД, который будет открываться только один раз в течение всей жизни вашего приложения... и когда приложение умирает, объект автоматически закрывается.
Вам лучше воспользоваться услугой по уходу за базой данных. При повороте экрана текущая компоновка со всеми компонентами уничтожается, а новая компоновка строится с использованием новой компоновки ориентации (в которой будут другие компоненты). Также у вас есть возможность заблокировать поворот экрана, если вы его не используете.