Android,当我们有多个表时,如何管理打开/关闭数据库连接?

时间:2012-09-07 07:20:52

标签: android database sqlite

我正在寻找处理数据库连接的最佳方法。我已根据以下方法设计了我的应用程序,并且工作正常。但是,有时应用程序崩溃,特别是在旧型号设备上。请看下面的方法。

我有一个DatabaseHelper类,这里将创建所有表。这个课程是这样的:

public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);

        Log.i(TAG, "Object created.");
    }

@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CRT_TBL_1);
        db.execSQL(CRT_TBL_2);
        db.execSQL(CRT_TBL_3);
        db.execSQL(CRT_TBL_4);
        db.execSQL(CRT_TBL_5);
        db.execSQL(CRT_TBL_6);
        db.execSQL(CRT_TBL_7);
        db.execSQL(CRT_TBL_8);
    }

@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(DatabaseHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data.");

        onCreate(db);
    }
}

如您所见,我有8个表,提供8种不同活动的数据。一个活动的处理程序类的实现类似于以下代码。

public class DatabaseHandler_1 {

    private final String TAG = "DatabaseHandler_1 ";

    private DatabaseHelper dbHelper;
    private SQLiteDatabase database;

    public DatabaseHandler_1 (Context context) {
        dbHelper = new DatabaseHelper(context);

        Log.i(TAG, "Object created.");
    }

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

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

// ... Other methods insert, update, query, ...
}

最后,根据所需信息,每项活动中将使用其中一项或部分信息。

public class Activity_1 {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "Try to create activity...");

        // Creating Database/Table
        dbHandler_1 = new DatabaseHandler_1 (this);
        dbHandler_1 .open();
        dbHandler_2 = new DatabaseHandler_2 (this);
        dbHandler_2 .open();
        dbHandler_3 = new DatabaseHandler_3 (this);
        dbHandler_3 .open();
    }

     @Override
     protected void onDestroy() {
        super.onDestroy();

        // Closing database
        dbRecipesHandler.close();
        dbFavoritsHandler.close();
        dbShoppingHandler.close();
     }

        // Other methods for displaying data...
}

当崩溃发生时,logcat显示我的应用程序尝试在数据库中查询时连接已关闭。我认为情况是这样的: 用户打开第1个活动,然后进入第二个活动,然后进入第三个活动。现在,如果用户单击后退按钮,则将关闭第三个活动,并且此活动的onDestroy()方法将关闭数据库连接。因为,第二个活动仍在内存中,活动假定连接仍处于打开状态,并且当它想要查询到数据库时,会发生崩溃。

Logcat显示如下消息:数据库连接已关闭。你想查询......

一个解决方案是让Android操作系统处理数据库连接,我们手动打开连接并使用它手动关闭它。 第二种解决方案是在Handler类中为每种方法手动打开和关闭连接。

你有什么建议?你有这方面的经验吗? 任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:0)

一般情况下,我建议您考虑使用Content Providers包装数据,然后在活动中使用Loaders将数据与UI混合。这可能看起来很多工作,但在内容提供商的众多好处中,您不必在活动中管理数据库连接或游标。 (注意,您的DatabaseHelper类将保持不变)

在我自己制作的不同应用程序中完成数据以及内容提供商的数据后,我会说内容提供商几乎总是可行的方式。在我的经验中,它总是变得更易于维护和扩展,而且你会获得许多自己构建成本非常高的功能。

那就是说,如果你真的更喜欢你目前使用的更直接的方法,我至少将你的连接的开放和关闭与活动的生命周期联系起来。只有在您实际需要数据的瞬间打开这些连接,获取该数据,然后立即关闭任何游标以及连接本身。

答案 1 :(得分:0)

最后我解决了这个问题。我以为我应该在活动中打开一次数据库。我试图在每个活动的onResume()方法中再次打开数据库,并在每个活动的onPause()中关闭它,而不是在onDestroy()方法中关闭。

到目前为止问题已经解决了。希望不要再看到它了。如果我再次面对它,那么将更新/删除答案。