无法返回Cursor对象 - close()方法是从来没有明确地称为错误 [英] Unable to return Cursor object - close() was never explicity called error

查看:462
本文介绍了无法返回Cursor对象 - close()方法是从来没有明确地称为错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿。我想一个游标对象返回到我的活动,其中它会在一个SimpleCursorAdapter使用的,但是我有一个 close()方法是从来没有明确地叫 错误。我无法找到此错误的任何解决方案,我要认为它是一个的无解误差的,LOL。

Hey. I'm trying to return a cursor object to my activity where its gonna be used in a SimpleCursorAdapter, but Im having a close() was never explicity called error. I cant find any solution for this error, and I'm about to think that its a non-solution error, LOL.

想和我在一起。

错误说:

close()方法从未明确要求   数据库   /data/data/com.example.myapp/databases/myDB.db

close() was never explicitly called on database '/data/data/com.example.myapp/databases/myDB.db'

和有警告过:

在终结​​释放语句。   请确保您显式调用   关闭()在你的光标:SELECT * FROM   contact_data ORDER BY时间递减

Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: SELECT * FROM contact_data ORDER BY duration desc

android.database.sqlite.DatabaseObjectNotClosedException:   应用程序没有关闭在这里打开的游标或数据库对象

android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

的误差是在该方法中,即在类DataHandlerDB(涉及数据库)

The error is in this method, that is in the class DataHandlerDB (deals with database)

public static Cursor selectTopCalls(Context ctx) {

        OpenHelper helper = new OpenHelper(ctx);
        SQLiteDatabase db = helper.getWritableDatabase(); // error is here

        Cursor cursor = db.query(TABLE_NAME_2, null, null, null, null, null,
                "duration desc");

        return cursor;
    }

此方法用于在我的活动,通过该方法如下:

This method is used on my activity, by this following method:

public void setBasicContent() {

    listview = (ListView) findViewById(R.id.list_view); 

    Log.i(LOG_TAG, "listview " + listview);

    Cursor c = DataHandlerDB.selectTopCalls(this); // here I use the method
    startManagingCursor(c);

    adapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] {               
            DataHandlerDB.CONTACT_NAME_COL,
            DataHandlerDB.CONTACT_NUMBER_COL,
            DataHandlerDB.CONTACT_DURATION_COL,
            DataHandlerDB.CONTACT_DATE_COL }, new int[] {
            R.id.contact_name, R.id.phone_number, R.id.duration, R.id.date });

    Log.i(LOG_TAG, "before setAdapter");

    Toast.makeText(this, "Before setAdapter", Toast.LENGTH_SHORT).show();

    listview.setAdapter(adapter);


}

我尝试关闭游标和数据库的这种方法中,但是当我这样做,错误是不固定的,它不打印我的列表中。

I try to close the cursor and database inside this method, but when I do that, the error is not fixed, and it doesnt print my list.

我试图关闭它在selectValues​​()方法,但如果这样做,它说,试图重新打开已经关闭游标(这样的事情的)。

I tried to close it on the selectValues() method, but when doing that, it says, trying to re-open cursor already closed (something like that).

我也试图关闭游标和数据库中的onDestroy()的onStop(),但它没有工作。

I also tried to close the cursor and database in onDestroy(), onStop() but it didnt worked.

这就是为什么我认为没有soluytion了点。我是什么supose办?

Thats why I thought there were no soluytion for that. What am I supose to do?

DataHandlerDB.java ,有CREATEDB()方法:

The class DataHandlerDB.java, has a createDB() method:

public static SQLiteDatabase createDB(Context ctx) {
        OpenHelper helper = new OpenHelper(ctx);
        SQLiteDatabase db = helper.getWritableDatabase();
        helper.onOpen(db);
        db.close();
        return db;
    }

和一个内部类名为 OpenHelper(扩展SQLiteOpenHelper)

public static class OpenHelper extends SQLiteOpenHelper {

        private final Context mContext;

        OpenHelper(Context context) {

            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.mContext = context;

        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            String[] sql = mContext.getString(
                    R.string.MyString_OnCreate).split("\n");

            db.beginTransaction();

            try {
                execMultipleSQL(db, sql);
                db.setTransactionSuccessful();
            } catch (SQLException e) {

                Log.e("Error creating tables and debug data", e.toString());
                throw e;

            } finally {
                db.endTransaction();

            }
        }

        private void execMultipleSQL(SQLiteDatabase db, String[] sql) {

            for (String s : sql) {

                if (s.trim().length() > 0) {

                    db.execSQL(s);
                }
            }

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            /*
             * Log.w("My Database",
             * "Upgrading database, this will drop tables and recreate.");
             * db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db);
             */
        }

        @Override
        public void onOpen(SQLiteDatabase db) {

            super.onOpen(db);
        }

    }

因此​​,任何人可以帮我解决这个问题?谢谢!

So anyone can help me to fix this problem?? Thanks!

推荐答案

而不是在你的每一个静态方法创建一个新的OpenHelper的,instantialize你的 DataHandlerDB 与当前上下文并有班级组织填充的 getWritableDatabase 的变量。您将创建不同的 SQLiteOpenHelper 对象和Android创建了多个游标对象不喜欢这样做。

Instead of creating a new OpenHelper in each of your static methods, instantialize your DataHandlerDB with the current context and have the class hold a variable populated by getWritableDatabase. You are creating multiple cursor objects created by different SQLiteOpenHelper objects and Android doesn't like doing this.

检查了这一点,了解更多信息: HTTP://www.ragtag。信息/ 2011 /月/ 1 /数据库陷阱/

Check this out for additional info: http://www.ragtag.info/2011/feb/1/database-pitfalls/

下面是它的外观像你对我正在做的事情......

Here's how it looks to me like you're doing things...

public class DataHandlerDB{

    public static SQLiteDatabase createDB(Context ctx) {
        OpenHelper helper = new OpenHelper(ctx);
        SQLiteDatabase db = helper.getWritableDatabase();
        ...
        return db;
    }

    public static Cursor selectTopCalls(Context ctx) {
        OpenHelper helper = new OpenHelper(ctx);
        SQLiteDatabase db = helper.getWritableDatabase(); // error is here
        ...
        return c;
    }

}

这导致了多个并发 SQLiteOpenHelper 对象和多个 SQLiteDatabase 对象和锁定情况下,你目前拥有。

This results in multiple concurrent SQLiteOpenHelper objects and multiple SQLiteDatabase objects and the locking situation you currently have.

,让你instantialize的一致背景下的DataHandler类,然后进行正常的电话(而不是静态的):

Instead of doing multiple Static calls, make a DataHandler class that you instantialize with the consistent context and then make normal calls (instead of static ones):

public class DataHandlerDB{
    OpenHelper _helper;
    SQLiteDatabse _db;

    public DataHandlerDB( Context ctx ){
        _helper = new OpenHelper(ctx);
        _db = _helper.getWritableDatabase();
    }

    public SQLiteDatabase createDB() {
        ...
        return db;
    }

    public Cursor selectTopCalls() {
        ...
        return c;
    }

}

public void setBasicContent() {

    ...

    DataHandlerDB handler = new DataHandlerDB( this );
    Cursor c = handler.selectValues();  //.selectTopCalls()?

    ...
}

在创建这个对象时,它会持续1 OpenHelper 1 SQLiteDatabase 。这会减轻问题的SQLite希望在关闭数据库,然后才能访问它。

When you create this object, it will persist 1 OpenHelper and 1 SQLiteDatabase. This should alleviate the problems with SQLite wanting the database closed before it can access it.

不要忘记关闭数据库在活动的onDestroy 方法。

Don't forget to close the DB in the onDestroy method of your activity.

这篇关于无法返回Cursor对象 - close()方法是从来没有明确地称为错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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