java.lang.IllegalStateException:尝试重新打开一个已关闭的对象 [英] java.lang.IllegalStateException: attempt to re-open an already-closed object

查看:217
本文介绍了java.lang.IllegalStateException:尝试重新打开一个已关闭的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出为什么有时我得到了IllegalStateException异常。我找不到说明了如何使用一个线程来查询SQLite数据库加载列表中的任何很好的例子。我包括我下面的code。它的大部分工作正常,但偶尔,我得到了IllegalStateException异常的时间。

我还得到了在我的另一项活动是ExpandableListActivity的一个实例,类似的异常。这种例外状态,试图重新查询一个已经关闭的游标。

谁能告诉我这样做了正确的方法,这样不会造成任何错误?我想preFER使用游标,而不是复制所有数据到内存中。如果我不能算出这个话,我将不得不加载所有到内存中。

我认为这个问题已经是与startManagingCursor(光标),事实上,数据库连接是关闭的onDestroy()。 plz帮助
- 故事

 公共类MyListActivity扩展ListActivity {
    私人MyCursorAdapter适配器;
    私人SQLiteDatabase DB = NULL;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);

        尝试 {
            新RetrieveCursorTask(本).execute((无效[])NULL);
        }赶上(例外五){
        }
    }

    @覆盖
    保护无效的onDestroy(){
        super.onDestroy();

        //空出的光标。
        如果(适配器!= NULL){
            adapter.changeCursor(空);
            适配器= NULL;
        }

        如果(DB = NULL和放大器;!&安培; db.isOpen()){
            db.close();
        }
    }

    私有类RetrieveCursorTask扩展的AsyncTask<虚空,虚空,光标> {
        私人上下文CTX;

        公共RetrieveCursorTask(上下文CTX){
            this.ctx = CTX;
        }

        @覆盖
        受保护的光标doInBackground(空... PARAMS){
            光标光标= NULL;
            DbHelper帮手=新DbHelper(CTX);

            尝试 {
                DB = helper.getReadableDatabase();
                光标= db.query(用户,
                    新的String [] {
                        DbHelper.ID_COLUMN,
                        DbHelper.UID_COLUMN
                    },
                    NULL,NULL,NULL,NULL,NULL);
                startManagingCursor(光标);
            }赶上(例外五){
            }
            返回游标;
        }

        @覆盖
        保护无效onPostExecute(光标指针){
            super.onPostExecute(光标);

            如果(光标!= NULL){
                尝试 {
                    适配器=新MyCursorAdapter(CTX,光标);
                }赶上(例外五){
                }
                setListAdapter(适配器);
            }
        }
    }

    私有类MyCursorAdapter扩展的CursorAdapter {
        私人上下文CTX;

        公共MyCursorAdapter(上下文的背景下,光标C){
            超(背景下,C);
            this.ctx =背景;
        }

        @覆盖
        公共无效bindView(查看视图,上下文的背景下,光标光标){
            // ...
        }

        @覆盖
        公共查看NewView的(上下文的背景下,光标光标的ViewGroup父){
            // ...
        }
    }
}
 

解决方案

。看看如果你想查询的数据库,你所希望的方式AsyncQueryHandler 的。

你的任务RetrieveCursorTask是在单独的线程,所以当你的活动被摧毁了你的AsyncTask可能仍运行在后台,但是因为你已经关闭了主要活动光标的OnDestroy它可能会再次您的AsyncTask返回后重新查询。运行

I'm trying to figure out why occasionally I'm getting the IllegalStateException. I can't find any good examples that show how to load a list using a thread to query a SQLite database. I've included my code below. Most of the time it works correctly, but occasionally, I'm getting the IllegalStateException.

I have also gotten a similar exception in another activity of mine that is an instance of ExpandableListActivity. That exception states "trying to requery an already closed cursor".

Can somebody tell me the correct way to do this so that it doesn't cause any errors? I would prefer to use the cursors instead of copying all of the data into memory. If I can't figure this out then I will have to load it all into memory.

I think the issue has something to do with startManagingCursor(Cursor) and the fact that the database connection is closed in onDestroy(). plz help
-- tale

public class MyListActivity extends ListActivity {
    private MyCursorAdapter adapter;
    private SQLiteDatabase db = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            new RetrieveCursorTask(this).execute((Void[]) null);
        } catch (Exception e) {
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // Null out the cursor. 
        if (adapter != null) {
            adapter.changeCursor(null);
            adapter = null;
        }

        if (db != null && db.isOpen()) {
            db.close();
        }
    }

    private class RetrieveCursorTask extends AsyncTask<Void, Void, Cursor> {
        private Context ctx;

        public RetrieveCursorTask(Context ctx) {
            this.ctx = ctx;
        }

        @Override
        protected Cursor doInBackground(Void... params) {
            Cursor cursor = null;
            DbHelper helper = new DbHelper(ctx);

            try {
                db = helper.getReadableDatabase();
                cursor = db.query("users",
                    new String[] {
                        DbHelper.ID_COLUMN,
                        DbHelper.UID_COLUMN
                    }, 
                    null, null, null, null, null);
                startManagingCursor(cursor);
            } catch (Exception e) {
            }
            return cursor;
        }

        @Override
        protected void onPostExecute(Cursor cursor) {
            super.onPostExecute(cursor);

            if (cursor != null) {
                try {
                    adapter = new MyCursorAdapter(ctx, cursor);
                } catch (Exception e) {
                }
                setListAdapter(adapter);
            } 
        }
    }

    private class MyCursorAdapter extends CursorAdapter {
        private Context ctx;

        public MyCursorAdapter(Context context, Cursor c) {
            super(context, c);
            this.ctx = context;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // ...
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // ...
        }
    }
}

解决方案

Look into AsyncQueryHandler if you want to query DB the way you want.

Your task RetrieveCursorTask is running on separate thread so when your activity gets destroyed your AsyncTask might still be running in background but as you have closed your cursor in main activity onDestroy it might be requeried again after your AsyncTask returns.

这篇关于java.lang.IllegalStateException:尝试重新打开一个已关闭的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆