尽管一切都关闭了,但 SQLite 连接泄漏了 [英] SQLite Connection leaked although everything closed

查看:24
本文介绍了尽管一切都关闭了,但 SQLite 连接泄漏了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了很多东西,比如close the connectionclose the cursor,但我做了所有这些事情.SQLite 连接仍然泄漏,我收到如下警告:

I found many stuff like close the connection and close the cursor, but I do all this stuff. Still the SQLite connection leaks and I get a warning like this:

A SQLiteConnection object for database was leaked!

我有一个数据库管理器,我使用以下代码在我的活动中调用它:

I have a database manager this, which I call in my activities with the following code:

DatabaseManager dbm = new DatabaseManager(this);

我的数据库管理器类的代码如下:

The code of my database manager class follows now:

public class DatabaseManager {

    private static final int DATABASE_VERSION = 9;
    private static final String DATABASE_NAME = "MyApp";
    private Context context = null;
    private DatabaseHelper dbHelper = null;
    private SQLiteDatabase db = null;


    public static class DatabaseHelper extends SQLiteOpenHelper {

         public DatabaseHelper(Context context) {
             super(context, DATABASE_NAME, null, DATABASE_VERSION);
         }

         @Override
         public void onCreate(SQLiteDatabase db) {

                   //create database tables
         }

         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                      //destroy and recreate them
         }

     }

     public DatabaseManager(Context ctx) {
         this.context = ctx;
     }

    private DatabaseManager open() throws SQLException {
        dbHelper = new DatabaseHelper(context);
        db = dbHelper.getWritableDatabase();

        if (!db.isReadOnly()) {
            db.execSQL("PRAGMA foreign_keys = ON;");
        }

        return this;
    }

    private void close() {
        dbHelper.close();
    }
}

当我调用数据库方法时,我会做以下事情:

When I call a database method, I do the following thing:

public Object getData() {

    open();

            //... database operations take place ...

    close();

    return data;
}

但正如我所说,我仍然收到此 SQLite 连接泄漏警告.

But as I said, I still get this SQLite connection leaked warning.

我做错了什么?

推荐答案

引文中的粗体对应于您代码中的这一部分:

The bolded font in the citation corresponds to this part in your code:

private DatabaseManager open() throws SQLException {
    dbHelper = new DatabaseHelper(context);
    db = dbHelper.getWritableDatabase();

来自:http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html

方法#1:使用抽象工厂实例化SQLiteOpenHelper

Approach #1: Use an Abstract Factory to Instantiate the SQLiteOpenHelper

将您的数据库助手声明为静态实例变量并使用抽象工厂模式来保证单例属性.这下面的示例代码应该让你对如何去做有一个好主意正确设计 DatabaseHelper 类.

Declare your database helper as a static instance variable and use the Abstract Factory pattern to guarantee the singleton property. The sample code below should give you a good idea on how to go about designing the DatabaseHelper class correctly.

静态工厂 getInstance 方法确保只有一个DatabaseHelper 将永远存在于任何给定时间.如果 mInstance对象尚未初始化,将创建一个.如果一个有已经创建,那么它将简单地返回.

你应该不要使用 new DatabaseHelper(context) 初始化您的辅助对象.
相反,始终使用DatabaseHelper.getInstance(context),因为它保证只有一个数据库助手将存在于整个应用程序的生命周期中.

The static factory getInstance method ensures that only one DatabaseHelper will ever exist at any given time. If the mInstance object has not been initialized, one will be created. If one has already been created then it will simply be returned.

You should not initialize your helper object using with new DatabaseHelper(context).
Instead, always use DatabaseHelper.getInstance(context), as it guarantees that only one database helper will exist across the entire application's lifecycle.

public static 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);
  }
}

这篇关于尽管一切都关闭了,但 SQLite 连接泄漏了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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