2014-06-13 4 views
1

좋은 하루 되세요.안드로이드 Sqlite IllegalStateException AsyncTask

그래서 이미지에서 가우시안 흐림을 계산하는 AsyncTask가 있습니다. Blob 필드를 사용하여 원본 이미지 데이터를 SQLite에서 검색하고 필터링 된 이미지를 SQLite에 저장합니다. 이 작업은 내 작업에서

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(); 

내가 (무작위로) 왜 때때로 모르는 내가 여기에 코드입니다 (setQuizData이 작업을 수행하는 기능입니다) 이 오류가 발생합니다 :

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 인스턴스를 만들어서 onec에만 액세스해야합니다.

도우미 자체가 동일한 연결을 사용하고 있는지 확인하기 위해 열린 방법이있을 수 있습니다.

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