什么时候关闭数据库是否必要?

时间:2013-03-29 13:56:57

标签: java android performance sqlite memory-management

我在这里看到很多关于它的帖子,但我不能让我的应用程序停止向我发送关于我没有关闭数据库的错误。我的DB有时是通过活动访问的,有时是来自后台类(服务)。

我使用DB

添加到活动中
protected void onDestroy() {
    Log.d("OnDestroy", "called");
    sqlAdapter helper = new sqlAdapter(StartScreen.this);
    helper.close();
    super.onDestroy();
}

正如许多文章所述,但它不会解决问题。

任何想法或解释都可以帮助我理解?应用程序没有崩溃或关于我没有关闭数据库的大量错误

谢谢!

2 个答案:

答案 0 :(得分:0)

每次完成后都应关闭它。如果您创建cursor来访问它,那么在获取数据并保存或完成处理后,您应该关闭cursor。然后在下次需要时再次打开它。 This answer应该帮助你

答案 1 :(得分:0)

在您的示例中,您似乎在onDestroy中创建了一个新对象,而不是关闭旧对象。所以,每次你做

sqlAdapter helper = new sqlAdapter(StartScreen.this);

您正在创建一个新对象,并且您将拥有大量未公开的引用,这就是导致警告的原因。

相反,看起来你可能正在寻找一个单例设计模式,它允许你在应用程序中维护一个对象,然后在onDestroy中关闭它。

public void onDestroy() {
    super.onDestroy();
    // close database
    final MySqlHelper helper = MySqlHelper.getInstance();
    helper.getDatabase().close();
}

否则它会一直开放到onDestroy,就像你现在正在尝试做的那样。当然,如果适当,您应该使用它,并且您正在应用程序中积极使用它。如果你很少使用数据库,你可以在每次使用后关闭它。

这个想法是,如果你做了适量的数据库,那么你正在减少数据库 open / close 调用,并且在这个用例中效率更高。

这是一个非常非常简单的单身人士的例子。

public class MySqlHelper extends SQLiteOpenHelper {
    static MySqlHelper mInstance = null;
    static SQLiteDatabase mDatabase = null;

    public static MySqlHelper getInstance() {
        if (mInstance == null) {
            // call private constructor
            mInstance = new MySqlHelper();
        }
        mDatabase = mInstance.getWritableDatabase();
        while(mDatabase.isDbLockedByCurrentThread() || mDatabase.isDbLockedByOtherThreads()) {
            // loop until available
        }
        return mInstance;
    }

    private MySqlHelper() {
        // mContext here is just a placeholder for your ApplicationContext
        // that you should have available to this class.
        super(mContext, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // all other filled out methods like onCreate, onUpgrade, etc
}

现在您可以使用它来实现数据源

public class MyDataSource {
    // Database fields
    private final SQLiteDatabase mDatabase;
    private final MySqlHelper mHelper;

    public MyDataSource() {
        mHelper = MySqlHelper.getInstance();
        mDatabase = mHelper.getDatabase();
    }

    // add your custom methods 

    private int update(ContentValues values, String whereClause) {
        int rowsUpdated = 0;
        synchronized (mDatabase) {
            rowsUpdated = mDatabase.update(MySqlHelper.TABLE_NAME, values, whereClause, null);
        }
        return rowsUpdated;
    }

    public int updateById(ContentValues values, int id) {
        final String whereClause = MySqlHelper.COLUMN_ID + "=" + id;
        return this.update(values, whereClause);
    }
}