我正在尝试将一个项目迁移到Android Room。阅读了Android Room文档后,我注意到Singleton适合访问我的数据库。
Android开发者的报价:
注意:如果您的应用程序在单个进程中运行,则在实例化AppDatabase对象时应遵循单例设计模式。每个RoomDatabase实例都相当昂贵,您很少需要在单个进程中访问多个实例。
我编写了以下代码:
@Database(entities = {Category.class, News.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static final String DB_NAME = "database.db";
private static AppDatabase instance;
public abstract CategoryDao categoryDao();
public abstract NewsDao newsDao();
private AppDatabase () {}
public static AppDatabase getInstance(Context context) {
if (instance == null) {
synchronized (AppDatabase.class) {
if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, DB_NAME).build();
}
}
}
return instance;
}
}
只是一个简单的双重检查锁定单例。
我读过一些指南/教程,几乎每个人都有类似的方法,但是我可以看到这种方法的一些问题:
Context
,即使您只需要一次来初始化Singleton。Context
可用的情况下访问数据库怎么办?有什么想法如何实现解决这些问题的房间数据库单例?
如果可能的话,我希望避免像Dagger2这样的DI库。
@Database(entities = {Category.class, News.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static final String DB_NAME = "database.db";
private static AppDatabase instance;
public abstract CategoryDao categoryDao();
public abstract NewsDao newsDao();
private AppDatabase () {}
// Use this to call on any place
public static AppDatabase getInstance() {
return instance;
}
// Use once to Create and setup the object
public static AppDatabase setInstance(Context context) {
if (instance == null) {
synchronized (AppDatabase.class) {
if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, DB_NAME).build();
}
}
}
return instance;
}
}
// Second you need to set instance on Application Class which create and make your DB
//Ready for Use Before anything perform
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
AppDatabase.setInstance(this)
}
}
使用
//Need to call
AppDatabase.getInstance().categoryDao();
您可以实例化数据库,然后锁定实例。
此外,调用上下文。applicationContext返回当前进程的单个全局应用程序对象的上下文。此上下文的生命周期与当前上下文相分离,当前上下文与进程的生命周期而不是当前组件相关联。
/**
* The Room Database that contains the item table.
*/
@Database(entities = arrayOf(Item::class), version = 1, exportSchema = false)
abstract class ItemDb : RoomDatabase() {
abstract fun itemDao(): ItemDao
companion object {
private var INSTANCE: ItemDb? = null
private val lock = Any()
@JvmStatic
fun getInstance(context: Context): ItemDb {
// When calling this instance concurrently from multiple threads we're in serious trouble:
// So we use this method, 'synchronized' to lock the instance
synchronized(lock) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.applicationContext, ItemDb::class.java, "items.db").build()
}
return INSTANCE!!
}
}
}
}
您可以初始化数据库并将其实例保存在应用程序类中,如下所示。
public class MyApplication extends Application {
public AppDatabase database;
@Override
public void onCreate() {
super.onCreate();
database = AppDatabase.getInstance(this)
}
}
稍后,您可以使用以下工具访问您的参考信息:
((MyApplication)activity).database
希望这会有所帮助。
在开发新产品时,我创建了一个后端和前端项目。对于前端,我使用带有Typescript的角度框架。下面是一个问题,因为我对这门语言还不熟悉(几天前)。我的问题是关于回调以及如何避免“this”上下文中的显式传递。我已经阅读了一些资源,我将链接它们。 下面我将为HttpClient实现一个包装器。快速版本是使用插件架构(由角度路由支持)的模块进行流控制,最好是通过使用观察员和订阅者广播401之类的错误
问题内容: 上周受本文启发,我正在重构我必须更明确地将上下文(数据库池,会话存储等)传递给处理程序的应用程序。 但是,我遇到的一个问题是,如果没有全局模板映射,我的自定义处理程序类型(要满足)上的方法将无法再访问该映射以呈现模板。 我需要保留全局变量,或者将我的自定义处理程序类型重新定义为结构。 有没有更好的方法来实现这一目标? func.go struct.go 有没有更干净的方法将实例传递给?
问题内容: 我以为这是我可以轻松搜索的东西,但也许我没有问正确的问题… 如何在给定的javascript函数中设置“ this”所指的内容? 例如,与大多数jQuery函数一样,例如: 如何编写/调用自己的独立函数,并在调用时具有适当的“ this”引用?我使用jQuery,因此,如果有jQuery特定的方式可以做到,那将是理想的选择。 问题答案: Javascript 和方法允许您设置函数的 上
问题内容: 如何传递上下文?我想打电话,如果在1000毫秒。我怎样才能做到这一点? 当我尝试上述操作时,指的是窗口。 问题答案: 编辑: 总而言之,早在2010年,当有人问这个问题时,解决此问题的最常用方法是保存对进行函数调用的上下文的引用,因为执行函数时要指向全局对象: 在一年前发布的ES5规范中,它引入了该方法,但最初的答案中并未建议使用该方法,因为该方法尚未得到广泛支持,您需要使用polyf
问题内容: 这个问题一定很明显,但我不知道。 在模板中,我链接到媒体目录中的js文件。从该文件中,我想访问一个{{my_chart}}之类的上下文变量。 问题答案: 我认为这样不可能。如果要访问视图提供的某些数据,则必须将其传递给js函数。 例 js文件: 视图 希望这可以帮助 :)