#android #sqlite #android-asynctask #illegalstateexception
#Android #sqlite #android-asynctask #исключение illegalstateexception
Вопрос:
Всем доброго дня.
Итак, у меня есть AsyncTask, который вычисляет размытие по Гауссу из изображения. Исходные данные изображения извлекаются из SQLite с помощью Blob-поля, также отфильтрованное изображение сохраняется в SQLite. Вот код (setQuizData — это функция, которая это делает):
public class SaveFilterTask extends AsyncTask<Void, Void, Void>{
private Context mContext;
private Context mApplicationContext;
private Quiz mQuiz;
public SaveFilterTask(Context context, Quiz quiz, Context applicationContext) {
super();
this.mContext = context;
this.mApplicationContext = applicationContext;
this.mQuiz = quiz;
}
@Override
protected Void doInBackground(Void... arg0) {
try {
setQuizData(mQuiz);
} catch (UnsupportedEncodingException e) {
cancel(true);
}
return null;
}
@Override
protected void onCancelled() {
Toast toast = Toast.makeText(mContext, R.string.error_loading_quiz, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
protected void onPreExecute() {
if(!((Activity)mContext).isFinishing()){
((MainActivity)mContext).showDialog();
}
}
protected void onPostExecute(Void args) {
if(!((Activity)mContext).isFinishing()){
((MainActivity)mContext).hideDialog();
}
Intent solveQuizIntent = new Intent(mContext, SolveQuizActivity.class);
solveQuizIntent.putExtra(
QuizConstants.KEY_PARCELABLE_FINISHED_QUIZ, mQuiz);
solveQuizIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(solveQuizIntent);
}
private void setQuizData(Quiz quiz) throws UnsupportedEncodingException {
if(quiz.getType().equals(QuizConstants.TYPE_PHOTO)){
QuizDataSource quizdatasource = new QuizDataSource(mApplicationContext);
quizdatasource.open();
String data = quizdatasource.getData(quiz.getId());
quizdatasource.close();
QuizDataSource quizdatasource2 = new QuizDataSource(mApplicationContext);
quizdatasource2.open();
String filterData = quizdatasource2.getDataFilter(quiz.getId());
quizdatasource2.close();
String filter = quiz.getFilter();
if(filter != null){
if(!filter.equals(QuizConstants.FILTER_DEFAULT)){
Bitmap original = decodeImage(data);
if(filterData == null){
data = FilterManager.applyFilter(original, quiz.getFilter());
Log.d("FilterManager","Data: " data);
Log.d("FilterManager","Id: " quiz.getId());
QuizDataSource quizdatasourceW = new QuizDataSource(mApplicationContext);
quizdatasourceW.open();
quizdatasourceW.setDataFilter(quiz.getId(), data);
quizdatasourceW.close();
}
}
}
}
}
private static Bitmap decodeImage(String data) {
byte[] b = Base64.decode(data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
}
Эта задача вызывается из моей деятельности, например:
SaveFilterTask sftask = new SaveFilterTask(this, quiz, getApplicationContext());
sftask.execute();
Я не знаю, почему иногда (и случайным образом) Я получаю эту ошибку:
0java.lang.RuntimeException: An error occured while executing doInBackground()
1at android.os.AsyncTask$3.done(AsyncTask.java:300)
2at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
3at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
4at java.util.concurrent.FutureTask.run(FutureTask.java:242)
5at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
6at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
7at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
8at java.lang.Thread.run(Thread.java:841)
9Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/Data.db
10at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
11at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1156)
12at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
13at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
14at QuizDataSource.getDataFilter(QuizDataSource.java:119)
15at SaveFilterTask.setQuizData(SaveFilterTask.java:82)
16at SaveFilterTask.doInBackground(SaveFilterTask.java:39)
17at SaveFilterTask.doInBackground(SaveFilterTask.java:1)
Я пробовал по-разному, используя одно соединение, используя одно соединение для операций чтения и одно для операции записи. Но ошибка сохраняется…
Есть идеи?
Спасибо.
Ответ №1:
Прежде всего, вы не должны каждый раз повторно инициализировать QuazDataSource.
Инициализируйте его в конструкторе и проверьте его с помощью
if (quizdatasource == null) {
quizdatasource = CreateaQuizDataSourceHelper().open;
}
Тогда вы всегда должны обязательно закрывать его, даже если он выходит из строя.
Cursor cursor = null;
try {
if (quizdatasource == null) {
quizdatasource = CreateaQuizDataSourceHelper().open;
}
cursor= quizdatasource.rawQuery(...);
} catch (Exception e) { e.printStackTrace(); }
finally {
if (quizdatasource != null) { quizdatasource.close(); }
}
по крайней мере, убедитесь, что ваши курсоры также закрыты, поместив проверку в блок finally.
if (cursor != null) { cursor.close; }
тогда вы не должны получать несколько экземпляров.
Вы также должны создать одноэлементный экземпляр вашей базы данных, чтобы убедиться, что к нему обращаются только один раз.
У самого помощника может быть такой открытый метод, чтобы убедиться, что он использует то же соединение.
public SQLiteDatabase open() {
SQLiteDatabase sqLiteDatabase = null;
try {
try {
sqLiteDatabase = this.getDatabaseConnection();
} catch (SQLiteException e) {
e.printStackTrace();
DataBaseConnectionPool.DbHelper DbHelper = this.dbHelper;
if (DbHelper != null) {
return this.dbHelper.getReadableDatabase();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sqLiteDatabase;
}