0

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

我有一个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 显示连接已关闭,而我的应用程序尝试在数据库中查询。我认为场景是这样的:用户打开第一个活动,然后他进入第二个活动,然后他进入第三个活动。现在,如果用户单击后退按钮,第三个活动将被关闭,并且此活动的 onDestroy() 方法将关闭数据库连接。因为,第二个活动仍在内存中,活动假设连接仍然打开,当它想查询数据库时,会发生崩溃。

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

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

你有什么建议?你有什么经验吗?任何建议将不胜感激。

4

2 回答 2

0

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

至此问题解决。希望不要再看到了。如果我再次面对它,那么将更新/删除答案。

于 2012-09-07T10:52:08.487 回答
0

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

在我制作的不同应用程序中以您的方式以及与内容提供者一起完成数据之后,我想说内容提供者几乎总是要走的路。根据我的经验,它总是最终变得更加可维护和可扩展,而且您会获得很多内置的功能,而这些功能自己构建起来非常昂贵。

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

于 2012-09-07T07:37:02.830 回答