Android的数据库连接和游标噢,我的(Android database connections

2019-09-18 18:47发布

我看了很多博客和教程就如何创建和采用Android工作时使用的数据库连接。 虽然我有很多工作的例子,不同的实现产生不同的问题。

例如,我用一个数据源类, Datasource和数据库辅助类, DBManagement

数据源

public class DataSource {
    // Database fields
    private SQLiteDatabase database;
    private DBManagement dbHelper;

    public SMSDataSource(Context context) {
        dbHelper = new DBManagement(context);
    }

    public void open() throws SQLException {
        if(database == null){
             database = dbHelper.getWritableDatabase();
        }
    }

public Cursor exampleCursor(long constraint){
    Cursor cur = database.query(DBManagement.TABLE_NAME,
            new String[] {DBManagement.Column}, "constraint="+constraint, null, null, null, null);
    return cur;
}
    //.. other methods down here which do rawQuery, QueryBuilder, etc.. 

DBManagement

public class DBManagement extends SQLiteOpenHelper{

    // .. table definitions and columns etc ..//

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

在我的活动范围内的onCreate方法,我会打电话给datasource.open()和SQL连接打开。 之后,我会做:

DataSource datasource = new DataSource();

Cursor cursor = datasource.exampleCursor(1);
startManagingCursor(cursor);

如果我浏览到一个新的活动,我得到以下错误:

 06-27 21:59:14.812: E/Database(13396): close() was never explicitly called on database '/data/data/com.example.package/databases/db.db' 

如果我添加datasource.close(); 到的onCreate结束,没有一个简单的游标适配器的工作,或者我得到的错误,如果一个conextual菜单上执行操作的数据库未打开。

什么是处理上述的最佳方式?

所以我做了以下内容,我仍然得到数据库的问题:

@Override
public void onBackPressed() {
    // do something on back.
    //Log.i(getClass().toString(), "onBackPressed");

    datasource.close();

    finish();
    return;
}

@Override
protected void onResume(){
    super.onResume();
    onCreate(null);
}


@Override
protected void onRestart(){
    datasource = new DataSource(this);
    datasource.open();

    filters = datasource.getFilterCursor();
    startManagingCursor(filters);

    super.onRestart();
}

@Override
protected void onPause(){
    //Log.i(getClass().toString(), "onPause");
    ((CursorAdapter) adapter).getCursor().close();
    datasource.close();
    super.onPause();
}   
@Override
protected void onStop(){
    //Log.i(getClass().toString(), "onStop");
    datasource.close();
    super.onStop();
}

Datasource.java类有以下几点:

public Datasource(Context context){
     dbHelper = new DBManagement(context);
}

public void open() throws SQLException {
    if( database == null ){
           database = dbHelper.getWritableDatabase();
    }
}

public void close(){
    if(dbHelper != null){
         dbHelper.close();
    }
}

Answer 1:

这其实是很简单的:

  • 完成(当使用显式地关闭所有光标 finally )等。
  • 不使用startManagingCursor()
  • 让你的数据库的包装/帮手/经理/不管类单
  • 不显式调用close()上的数据库帮手 。 我会当你的进程终止时自动关闭。

另外:频繁的开启和关闭,绝对是一个坏主意,因为它会带来相当多的开销。

使用装载机也是一种选择。 你绝对不需要使用内容提供商使用装载机,但这不是那么简单,因为它可以。 使用一个内容提供商包括IPC通常是矫枉过正,如果你不打算将数据导出到其他应用程序。



Answer 2:

如果你打开你的数据库onCreate那么你可以关闭上onDestroy



Answer 3:

“理想”的解决你的问题是过渡到Content ProvidersLoaders ,并使用v4保持兼容库的向后兼容性。 这样做,解决了这个问题,因为你不再计较打开和关闭数据库连接,你在后台而不是UI线程执行数据库操作的好处。

这也证明未来您的应用程序,因为startManagingCursor已被弃用。 它仍然可以使用,现在,即使是在4.1,但它会在某个时候被移除。

我对使用内容提供商另一篇文章在这里 ,即进入其他原因使用提供,并提供了一个链接到一个教程。

我觉得最大的失败,对谷歌的一部分ContentProvider是,没有提供一个简单而直观的方式来构建它们。



Answer 4:

我会坚持,你从你的数据库完成数据的抓取,尽快关闭数据库连接。 也是最好的办法是,开放和内再次关闭onResume()onPause()



Answer 5:

我记得有一个类似的问题,我只是重新每当我打电话getWritableDatabase()在新的活动不收旧引用错误。 当我关闭SQLiteDatabase对象database SQLiteOpenHelper对象dbHelper我不再接收这些错误。

public void close() {
    // Check against the database being created but not opened, close writable db
    if(database != null) {
        database.close();
        database = null;
    }

    // In case someone calls DataSource.close() more than once...
    if(dbHelper != null) {
        dbHelper.close();
        dbHelper = null;
    }
}

希望帮助!



文章来源: Android database connections and cursors oh my