1

SQLiteOpenHelper を拡張する DatabaseHelper クラスでは、DatabaseHelper 以外のクラス内でクエリを実行しないように、Cursors を他のアクティビティに返すさまざまなメソッドを設定しました。これらのメソッドでは、後でカーソルまたはデータベースを閉じず、次のように返します。

public Cursor getCoursesLeft()
{
    // Open a readable database.
    SQLiteDatabase database = this.getReadableDatabase();

    // Query the database and return the cursor.
    return database.query(DEGREE_PLAN_TABLE, null, DEGREE_COLUMN_TAKEN + " = ?",
            new String[] { "0" }, null, null, DEGREE_COLUMN_CLASS_NAME + " COLLATE NOCASE");
}

どのアクティビティからメソッドを呼び出しても、使用後に返された Cursor を必ず閉じます。

Cursor はオブジェクトなので、参照渡しする必要がありますね。したがって、他のアクティビティから閉じると元のオブジェクトが閉じられるはずです。正しく理解できれば、カーソルを閉じるとデータベースも閉じます。

これは悪いコーディング方法ですか?

データベースで close が呼び出されなかったことを示す LogCat エラーがランダムに発生するようです。コードで見つけられる理由は、これらのメソッドでカーソルを返す方法だけです。

4

2 に答える 2

1

正しく理解できれば、カーソルを閉じるとデータベースも閉じます。

それは正しく聞こえません。すべてのカーソルを閉じた後、データベースを明示的に閉じる必要があります。logcatエラーは、データベースを閉じておらず、おそらくデータベースの別のインスタンスを開こうとしていることが原因です。

順序は重要です。最初にカーソル、次にDBインスタンスです。

<bad joke in 3.. 2.. 1...>

残りは悪い習慣のようには聞こえません、あなたがそれをdbしなければならないとき、あなたはそれをdbしなければなりません。:D

[編集]:あなたはこれをやったと言った:

public Cursor getCoursesLeft()
{
    // Open a readable database.
    SQLiteDatabase database = this.getReadableDatabase();
                   ^^^ here you're creating a new instance of the db
which means the db is opened for reading, and the scope of this variable
is lost outside this function. This means you can not close this instance explicitly

    // Query the database and return the cursor.
    return database.query(DEGREE_PLAN_TABLE, null, DEGREE_COLUMN_TAKEN + " = ?",
            new String[] { "0" }, null, null, DEGREE_COLUMN_CLASS_NAME + " COLLATE NOCASE");
}

代わりに、このメソッドの外部からアクセスできるデータベース変数を用意し、カーソルの操作が完了したら(そしてカーソルを閉じたら)閉じます。

SQLiteDatabase database;
public Cursor getCoursesLeft()
{
    // Open a readable database.
    database = this.getReadableDatabase();

    // Query the database and return the cursor.
    return database.query(DEGREE_PLAN_TABLE, null, DEGREE_COLUMN_TAKEN + " = ?",
            new String[] { "0" }, null, null, DEGREE_COLUMN_CLASS_NAME + " COLLATE NOCASE");
}
public void someOtherFunction() {
  Cursor blah = getCoursesLeft();
  // do something with blah
  blah.close();
  database.close();
}
于 2013-01-01T17:26:04.023 に答える
0

カーソルを閉じないと、メモリリークが発生します。データベースを閉じることは異なります。

.fileカーソルを閉じることは、カーソルの作成時に生成された特定のファイルへの特定の接続を閉じることに似ています。

したがって、常にカーソルを閉じる必要があります。

これは悪いコーディングですか?

いいえ、そうです。アクティビティがこれらの一時ファイルを台無しにしないでください。何も起こらないが、それはただ良くないようだ

于 2013-01-01T17:33:17.793 に答える