使用Singleton设计模式的SQLiteDatabase模式、Singleton、SQLiteDatabase

2023-09-11 20:14:55 作者:絀嫁ア泩活

我是新手,而在Android上,和我工作的一个简单的应用程序来获得一些基本经验。我的应用程序是pretty的简单,包括一间广播接收器和一些活动的其他东西。这两个组件使用一个单一的数据库,所以在理论上是可能发生的都试图同时访问该数据库。

I'm rather newbie on Android, and I'm working on a simple application to get some basic experience. My app is pretty simple and consists among other things of a broadcast receiver and some activities. Both components make use of a single database, so in theory it could happen that both try to access the db concurrently.

目前我只是实例化数据库对象(也就是,一个SQLite数据库辅助类),每个我需要它的时候,并执行所需的操作:查询,插入等

Currently I'm simply instantiating the db object (which is-a SQLite db helper class) each time I need it, and performing the needed operations: query, insert, etc.

这是我一直在阅读这里和其他一些文件,这有得到一个的情况下分贝的并发访问,DB锁定异常的问题,所以更好的办法是有此数据块单一实例对象,以便所有组件都使用在任何时候都相同的数据库连接。

From what I've been reading here and in some other documents, this has the problem of getting a "db locked" exception in case the db is accessed concurrently, so a better approach would be having a single instance of this db object so all components use the same db connection at all times.

时的上述推论是否正确?将一个单则是这是一个足够好的解决办法?我知道有些较真可能会反对,但请注意,这是一个相当简单的应用程序,这样我买得​​起做的事情我也不会在其他情况下。

Is the above reasoning correct? Would a singleton then be a good-enough solution for this? I know some purists may argue against it, but please note that this is a rather simple application so I can afford doing things I wouldn't in other cases.

否则,你会是更好的选择呢?我读过关于使用内容提供商,但它会是太多这一点,除此之外我没有兴趣与其他活动共享数据。我确实阅读post并发现它相当有帮助的。

Otherwise, what would a better option be? I've read about using content provider but it would be too much for this, besides that I'm not interested to share the data with other activities. I have indeed read this post and found it rather helpful.

在此先感谢。

推荐答案

下面是一些示例code,说明了三种可能的途径。这些将允许访问该数据库整个应用程序。

Click here to see my blog post on this subject.

Here is some sample code that illustrates three possible approaches. These will allow access to the database throughout the application.

这是不完整的实现,但它应该给你如何去正确地设计 DatabaseHelper 类是一个好主意。静态工厂方法确保了在任何时间仅存在一个DatabaseHelper实例。

This isn't the complete implementation, but it should give you a good idea on how to go about designing the DatabaseHelper class correctly. The static factory method ensures that there exists only one DatabaseHelper instance at any time.

/**
 * create custom DatabaseHelper class that extends SQLiteOpenHelper
 */
public class DatabaseHelper extends SQLiteOpenHelper { 
    private static DatabaseHelper mInstance = null;

    private static final String DATABASE_NAME = "databaseName";
    private static final String DATABASE_TABLE = "tableName";
    private static final int DATABASE_VERSION = 1;

    private Context mCxt;

    public static DatabaseHelper getInstance(Context ctx) {
        /** 
         * use the application context as suggested by CommonsWare.
         * this will ensure that you dont accidentally leak an Activitys
         * context (see this article for more information: 
         * http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html)
         */
        if (mInstance == null) {
            mInstance = new DatabaseHelper(ctx.getApplicationContext());
        }
        return mInstance;
    }

    /**
     * constructor should be private to prevent direct instantiation.
     * make call to static factory method "getInstance()" instead.
     */
    private DatabaseHelper(Context ctx) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.mCtx = ctx;
    }
}

方法2:抽象与`ContentProvider`

SQLite数据库

这是我建议的方法。其一,新的 CursorLoader 类需要的ContentProvider S,所以如果你想要一个活动或片段实施 LoaderManager.LoaderCallbacks<光标> CursorLoader (我建议你好好把握,这是不可思议的!),你会需要实施的ContentProvider 为您的应用程序。此外,你不必担心做一个单身数据库佣工ContentProviders。只需拨打 getContentResolver()的活动,系统会照顾一切为你(换句话说,没有必要设计一个Singleton模式,以prevent从正在创建多个实例)。

Approach #2: abstract the SQLite database with a `ContentProvider`

Android 数据库 SQLite 数据库 卢已好运哒 CSDN博客

This is the approach I would suggest. For one, the new CursorLoader class requires ContentProviders, so if you want an Activity or Fragment to implement LoaderManager.LoaderCallbacks<Cursor> with a CursorLoader (which I suggest you take advantage of, it is magical!), you'll need to implement a ContentProvider for your application. Further, you don't need to worry about making a Singleton database helper with ContentProviders. Simply call getContentResolver() from the Activity and the system will take care of everything for you (in other words, there is no need for designing a Singleton pattern to prevent multiple instances from being created).

希望这有助于!