0

I have met a problem of java.lang.IllegalStateException: attempt to re-open an already-closed object when extracting ALL data from a database using a AsyncTask...It seems that I have not closed the database until onPostExecute I have researched some similar questions in this site and tried to follow and solve but still being unsucessful.

Exercises_MainActivity class:

private class ExtractDB extends AsyncTask<Void, Void, Void> 
{
    @Override
    protected void onPreExecute()
    {           
        Ex_dbHlp.open();
    }

    @Override
    protected Void doInBackground(Void... params) 
    {            
        exercises = Ex_dbHlp.get_All_Ex_Data();     // LINE 223     
        return null;
    }

    protected void onPostExecute(Void result) 
    {
        Ex_dbHlp.close();
        int i = exercises.size();       
        for (int j = 0; j < i; j++)     {Inflate_All_Ex_Data(j);}       
        if (i==0)                       {Inflate_All_Ex_Data (0);}
    }       
}   

DatabaseHelper:

public ArrayList<Exercise> get_All_Ex_Data()
{
    String[] columns = {COL_id, COL_ex_group, COL_ex_name, COL_ex_cal};
    Cursor cursor = database.query(TABLE_NAME, columns, null, null, null, null, COL_id);  //LINE 402
    ArrayList<Exercise> Exercises = new ArrayList<Exercise>();
    while(cursor.moveToNext()){
        String id = cursor.getString(0);
        String ex_group = cursor.getString(1);
        String ex_name = cursor.getString(2);
        String ex_cal = cursor.getString(3);            
        Exercise exercise = new Exercise(id, ex_group, ex_name, ex_cal);
        Exercises.add(exercise);            
    }
    cursor.close();
    return Exercises;           
}

Logcat:

08-14 00:29:07.136: E/AndroidRuntime(32372): FATAL EXCEPTION: AsyncTask #2
08-14 00:29:07.136: E/AndroidRuntime(32372): java.lang.RuntimeException: An error occured while executing doInBackground()
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.lang.Thread.run(Thread.java:856)
08-14 00:29:07.136: E/AndroidRuntime(32372): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.abc.abc/databases/abc
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1156)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at com.abc.abc.Abc_Ex_DataBaseHelper.get_All_Ex_Data(Abc_Ex_DataBaseHelper.java:402)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at com.abc.abc.Exercises_MainActivity$ExtractDB.doInBackground(Exercises_MainActivity.java:224)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at com.abc.abc.Exercises_MainActivity$ExtractDB.doInBackground(Exercises_MainActivity.java:1)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-14 00:29:07.136: E/AndroidRuntime(32372):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-14 00:29:07.136: E/AndroidRuntime(32372):    ... 5 more
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
pearmak
  • 4,979
  • 15
  • 64
  • 122

2 Answers2

0

You have to close your cursor in get_All_Ex_Data(), after your loop.

The thing you open and close in onPreExecute and onPostExecute is the db helper.

Edit : is your database helper a singleton ? You have an example of a singleton here: Using Singleton design pattern for SQLiteDatabase

Community
  • 1
  • 1
Romain Guidoux
  • 2,943
  • 4
  • 28
  • 48
  • thanks Romain Guidoux for your advice! I have added the cursor.close() after the loop but seems the logcat still reports the same error... – pearmak Aug 13 '13 at 16:33
0

I have tried to move the Ex_dbHlp.open(); to the doInBackground instead of onPreExecute and then it works!! But I dont know why this works...

private class ExtractDB extends AsyncTask<Void, Void, Void> 
{
    @Override
    protected void onPreExecute()
    {           

    }

    @Override
    protected Void doInBackground(Void... params) 
    {            
        Ex_dbHlp.open();
        exercises = Ex_dbHlp.get_All_Ex_Data();
        return null;
    }

    protected void onPostExecute(Void result) 
    {
        Ex_dbHlp.close();
        int i = exercises.size();       
        for (int j = 0; j < i; j++)     {Inflate_All_Ex_Data(j);}       
        if (i==0)                       {Inflate_All_Ex_Data (0);}
    }       
pearmak
  • 4,979
  • 15
  • 64
  • 122