Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 何时必须关闭数据库?_Java_Android_Performance_Sqlite_Memory Management - Fatal编程技术网

Java 何时必须关闭数据库?

Java 何时必须关闭数据库?,java,android,performance,sqlite,memory-management,Java,Android,Performance,Sqlite,Memory Management,我在这里看到了很多关于它的帖子,但我就是无法让我的应用程序停止向我发送关于我没有关闭数据库的错误。我的数据库有时由活动访问,有时由后台类(服务)访问 我添加到活动的使用数据库 protected void onDestroy() { Log.d("OnDestroy", "called"); sqlAdapter helper = new sqlAdapter(StartScreen.this); helper.close(); super.onDestroy()

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

我添加到活动的使用数据库

protected void onDestroy() {
    Log.d("OnDestroy", "called");
    sqlAdapter helper = new sqlAdapter(StartScreen.this);
    helper.close();
    super.onDestroy();
}
正如许多帖子中所建议的,但这并不能解决问题

有什么想法或解释来帮助我理解吗?该应用程序没有崩溃或任何东西,但我没有关闭数据库的错误很多


谢谢

每次完成后都应该关闭它。如果您创建了一个
光标
来访问它,那么在您获取数据并保存它或完成对它的处理之后,您应该关闭
光标
。然后下次需要时再打开它。在您的示例中,

似乎是在
onDestroy
中创建新对象,而不是关闭旧对象。所以每次你这么做

sqlAdapter helper = new sqlAdapter(StartScreen.this);
您正在创建一个新对象,将有大量未关闭的引用,这就是导致警告的原因

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

public void onDestroy() {
    super.onDestroy();
    // close database
    final MySqlHelper helper = MySqlHelper.getInstance();
    helper.getDatabase().close();
}
否则,它将保持打开状态,直到
onDestroy
,就像您现在尝试的那样。如果合适的话,当然应该使用它,并且您正在应用程序中积极地使用它。如果您很少使用数据库,那么每次使用后关闭它就可以了

这样做的想法是,如果您进行适量的数据库打开/关闭调用,您将减少这些调用,并且在该用例中会更加高效

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

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

始终发布您声称的内容?我只想指出,在使用连接池的情况下,这不一定是真的。我不认为在这种情况下是这样的,但是在使用连接池时关闭连接会破坏使用连接池的目的。