从数据库中提取除"attempt to re-open an already-closed object"以外的所有数据



当使用AsyncTask从数据库中提取所有数据时,我遇到了java.lang.IllegalStateException: attempt to re-open an already-closed object的问题。。。我似乎直到onPostExecute才关闭数据库我在这个网站上研究了一些类似的问题,并试图跟踪和解决,但仍然没有成功。

练习_MainActivity类:

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

数据库帮助程序:

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

我尝试将Ex_dbHlp.open();移动到doInBackground而不是onPreExecute,然后它就工作了!!但我不知道为什么这样。。。

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

循环结束后,必须关闭get_All_Ex_Data()中的光标。

在onPreExecute和onPostExecute中打开和关闭的是db助手。

编辑:你的数据库助手是一个单例吗?这里有一个singleton的例子:使用SQLiteDatabase 的singleton设计模式

最新更新