0

java.lang.IllegalStateException: attempt to re-open an already-closed object我在使用...从数据库中提取所有数据时遇到了一个问题AsyncTask,我似乎没有关闭数据库,直到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;           
}

日志猫:

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
4

2 回答 2

0

在循环之后,您必须在 get_All_Ex_Data() 中关闭光标。

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

编辑:您的数据库助手是单身人士吗?您在这里有一个单例示例:使用 SQLiteDatabase 的单例设计模式

于 2013-08-13T16:27:26.703 回答
0

我试图将其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);}
    }       
于 2013-08-13T16:40:28.487 回答