为SQLiteDatabase使用Singletondevise模式

我是Android新手,我正在做一个简单的应用程序来获得一些基本的经验。 我的应用程序非常简单,包括广播接收器和其他一些活动。 这两个组件都使用单个数据库,所以理论上可能会同时尝试访问数据库。

目前我只是简单地实例化db对象(这是一个SQLite数据库帮助类),每次我需要它,并执行所需的操作:查询,插入等

从我在这里和其他一些文档中读到的,这有一个问题,即在数据库被并发访问的情况下,获得一个“数据库locking”exception,所以更好的方法是有一个这个数据库对象的实例,所以所有组件始终使用相同的db连接。

上述推理是否正确? 单身人士是否会成为一个足够好的解决scheme呢? 我知道一些纯粹主义者可能会反对,但请注意,这是一个相当简单的应用程序,所以我可以负担得起的事情,我不会在其他情况下。

否则,更好的select是什么? 我已经阅读过关于使用内容提供者的内容,但是这对我来说太多了,除此之外,我不想与其他活动分享数据。 我确实看过这篇文章 ,发现它相当有帮助。

点击这里查看关于这个主题的博客文章。


以下是一些示例代码,说明了三种可能的方法。 这些将允许在整个应用程序中访问数据库。

方法1:让`SQLiteOpenHelper`成为一个静态数据成员

这不是完整的实现,但它应该给你一个关于如何正确deviseDatabaseHelper类的好主意。 静态工厂方法确保在任何时候只存在一个DatabaseHelper实例。

 /** * 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数据库

这是我build议的方法。 首先,新的CursorLoader类需要ContentProvider ,所以如果你想要一个Activity或者Fragment来实现LoaderManager.LoaderCallbacks<Cursor>和一个CursorLoader (我build议你利用它,这太神奇了!),你需要为您的应用程序实现一个ContentProvider 。 此外,您不必担心使用ContentProviders创buildSingleton数据库帮助器。 只需从Activity中调用getContentResolver() ,系统将为您处理所有事情(换句话说,不需要devise单例模式来防止创build多个实例)。

希望这可以帮助!

我从来没有读过关于使用单身来访问Android上的分贝。 你介意提供一个关于这个的链接。

在我的应用程序中,我使用简单的dbhelper对象,而不是单例,我认为这是更多的SQL引擎的工作,以确保数据库没有locking,而不是你的android类的工作,它工作得很好,我的最大的应用程序是中等大小。

更新#1:看看你给的参考,看起来问题不是关于使用dbhelper不同实例。 即使一个实例访问数据库也会遇到问题:问题来自并发访问。 因此,确保不同线程正确访问数据库的唯一方法是使用简单的线程同步机制( synchronized方法或块),而且与使用单例无关。

更新#2:你提供的第二个链接清楚地表明,在multithreading同时在db中写入的情况下,他们需要单例dbhelper对象。 例如,如果您从AsyncTasks执行sql操作(插入/更新/删除),就会发生这种情况。 在这种情况下,单例对象dbhelper只需将所有的sql操作放在某种stream水线中,然后按顺序执行。

这个解决scheme比在java中使用同步方法使用正确的线程同步更容易实现。 其实我觉得应该有更多的强调在Android文档的这个问题的地方,并鼓励使用单身db辅助工具。

感谢这个不错的问题和跟进。