2014-06-13 30 views
1

美好的一天每個人。在AsyncTask上的Sqlite IllegalStateException

所以,我有一個AsyncTask從圖像中計算高斯模糊。使用Blob字段從SQLite中檢索原始圖像數據,過濾後的圖像也存儲在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) 

我嘗試用不同的方式,使用單一連接,使用的讀操作的寫操作一個連接和一個。但錯誤仍然存​​在......

任何想法?

謝謝。

回答

0

首先你不應該每次都重新初始化QuazDataSource。

初始化它在Construcotr和使用

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; } 

那麼你不應該得到多個實例。

您還應該創建數據庫的SINGLETON實例,以確保它只能訪問一個。

Helper本身可能有這樣一個開放的方法來確保它使用相同的連接。

​​