SQLite什么时候应该关闭db和cursor?我应该使用异步调用吗?

时间:2015-07-20 10:31:42

标签: android android-sqlite android-cursor

这个问题是对此的后续问题:

When should I close a cursor and db?

我正在学习如何使用SQLite for Android,我正在使用本教程作为示例:

http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

当他们关闭数据库或游标时,我没有看到任何一致性。例如,这个方法关闭了db:

public void addContact(Contact contact) 
{
SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();
values.put(KEY_NAME, contact.getName()); // Contact Name
values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone Number

// Inserting Row
db.insert(TABLE_CONTACTS, null, values);
db.close(); // Closing database connection
}

但就在它之后,这种方法并没有关闭它:

public Contact getContact(int id) {
SQLiteDatabase db = this.getReadableDatabase();

Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
        KEY_NAME, KEY_PH_NO }, KEY_ID + "=?",
        new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
    cursor.moveToFirst();

Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
        cursor.getString(1), cursor.getString(2));
// return contact
return contact;
}

关闭光标也一样。

为什么在添加联系人之后关闭数据库是正确的,但在获取联系人之后却没有?调用getWritableDatabase()getReadableDatabase()后始终关闭数据库是一个好习惯吗?另外,如果我想向数据库中添加几个项目,那么保持与数据库的连接打开并逐个插入许多项目是一个好习惯,还是应该以一种查询方式将它们全部插入到一起?

我还读过您希望使用getWritableDatabase()getReadableDatabase()来呼叫AsyncTaskIntentService,但教程中的方法会连续使用它。哪种更好的做法?

1 个答案:

答案 0 :(得分:0)

是的,应该在使用后始终关闭数据库连接。

可写数据库连接更容易受到攻击,因为某些其他进程可能会访问未关闭的数据库连接并对数据库进行更改。他们不能通过未封闭的可读数据库连接来做。

应尽可能减少内存泄漏。 我昨天刚才回答了类似的问题。这是:

Java中的内存泄漏是应用程序不再使用某些对象的情况,但垃圾收集无法将它们识别为未使用,因此不会清除它。

每次创建对象时,内存中的一些空间都保留给该对象。对于任何数据库连接都是一样的。因此,在使用连接后,如果你不关闭它,GC不会知道该对象将不再被使用,因此不会删除它。因此,它会留在内存中,在程序的其余部分运行时会占用宝贵的资源。 [因此资源泄漏]。

这完全不需要。此外,这会使您的程序暴露于安全问题,因为连接是开放的,它是易受攻击的,并且可以对数据库进行更改。请记住,即使在Activity关闭后,如果有正在运行的线程或AsyncTask,数据库连接也会随线程一起打开。

进一步阅读:What is a “Memory leak” in Java?

来自StackOverflow:Closing database connection to avoid memory leak