SQLite 连接对象泄露 - Android

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21496221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:39:43  来源:igfitidea点击:

SQLite connection object leaked - Android

androidsqlitememory-leakssqliteopenhelper

提问by user3164083

I am making my first android app, and I took some sqlite tutorials first, that taught me to use a databaseHelper that extends SQLiteOpenHelper. So my databaseHelper does extend SQLiteOpenHelper. I get a sqlite connection leak warning in the Logcat so would like some advice about what to do to fix that.

我正在制作我的第一个 android 应用程序,我首先学习了一些 sqlite 教程,这些教程教会了我使用扩展 SQLiteOpenHelper 的 databaseHelper。所以我的 databaseHelper 确实扩展了 SQLiteOpenHelper。我在 Logcat 中收到了一个 sqlite 连接泄漏警告,因此想要一些有关如何解决该问题的建议。

I get this error:

我收到此错误:

02-01 21:39:50.740: W/SQLiteConnectionPool(32061): A SQLiteConnection object for database '/data/data/com.btf271.fashionassistant/databases/clothingManager' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

My databaseHelper functions that are called where the leak occurs:

在发生泄漏的地方调用我的 databaseHelper 函数:

 public List<Sticker> getObjectsByGenderAndCategory(String gender, String category) {
        List<Sticker> objects = new ArrayList<Object>();
        String selectQuery = String.format(
                "SELECT * FROM %s WHERE %s = \"%s\" AND %s = \"%s\"",
                TABLE_OBJECT, KEY_GENDER, gender, KEY_CATEGORY, category);

        Log.e(LOG, selectQuery);

        SQLiteDatabase db = this.getReadableDatabase();
        Cursor c = db.rawQuery(selectQuery, null);
     try{
        // looping through all rows and adding to list
        if (c.moveToFirst()) {
            do {
                Object o = createClothingItemJavaObject(c);

                // adding to object list
                objects.add(o);
            } while (c.moveToNext());
        }
     }finally {
           c.close();
db.close();
     }
        return objects;
    }

I found this which I will try tomorrow. It's late.

我找到了这个我明天会尝试的。晚了

Thanks.

谢谢。

回答by user3164083

All I did was implement this answer to a similar questionand now it doesn't show the SQL connection object leak error. I cannot recommend this enough. It only took a few minutes to implement and worked.

我所做的只是对类似问题实施此答案,现在它没有显示 SQL 连接对象泄漏错误。我不能推荐这个。实施和工作只需要几分钟。

Here is the code:

这是代码:

public class DatabaseHelper extends SQLiteOpenHelper { 

  private static DatabaseHelper mInstance = null;

  private static final String DATABASE_NAME = "database_name";
  private static final String DATABASE_TABLE = "table_name";
  private static final int DATABASE_VERSION = 1;

  public static DatabaseHelper getInstance(Context ctx) {

    // Use the application context, which will ensure that you 
    // don't accidentally leak an Activity's context.
    // See this article for more information: http://bit.ly/6LRzfx
    if (mInstance == null) {
      mInstance = new DatabaseHelper(ctx.getApplicationContext());
    }
    return mInstance;
  }

  /**
   * Constructor should be private to prevent direct instantiation.
   * make call to static factory method "getInstance()" instead.
   */
  private DatabaseHelper(Context ctx) {
    super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
  }
}

回答by Javi Martínez

I fixed this by adding

我通过添加解决了这个问题

@Override
protected void finalize() throws Throwable {
    this.close();
    super.finalize();
}

to my SQLiteOpenHelper extended class

到我的 SQLiteOpenHelper 扩展类

回答by laalto

Match each call to getReadableDatabase()and getWritableDatabase()to a corresponding close()on the same database object.

将每次调用getReadableDatabase()与同一数据库对象上的getWritableDatabase()相应调用相匹配close()

For example, your getAllClothingItemsByGenderAndCategory()calls getReadableDatabase()but does not close()it. Add db.close()after c.close().

例如,您的getAllClothingItemsByGenderAndCategory()电话getReadableDatabase()但没有close()db.close()之后添加c.close()

Your closeDB()makes no sense since it gets a new reference to the database with getReadableDatabase()and closes just that. It does nothing to close any existing database connection.

closeDB()没有任何意义,因为它获得了对数据库的新引用getReadableDatabase()并关闭了。它不会关闭任何现有的数据库连接。

回答by laalto

Each time you open a database(readable or writable) and cursor which uses memory resources has to be deallocated by using ".close();" after its usage ends in each database function.. by your_database object.close(); and cursor object.close();

每次打开数据库(可读或可写)时,必须使用“.close();”释放使用内存资源的游标。在每个数据库函数中使用结束后..通过 your_database object.close(); 和游标 object.close();