Q1:请让我知道下面两种实现方式之间的区别(关于获取领域实例).我想知道哪一个更快,更轻巧,推荐什么?
1.设置并获取领域为默认值(具有特定配置)
private void setupCustomRealm() {
if (!Utils.isStringHasText(databaseName)) {
databaseName = DbManager.getInstance().getCurrentDb();
}
// get config
RealmConfiguration config = getRealmConfigByDBName(databaseName);
Realm.setDefaultConfiguration(config);
Realm.compactRealm(config);
}
public Realm getCustomRealm() {
if (firstTime) {
setupCustomRealm();
}
return Realm.getDefaultInstance();
}
2.直接从配置获取Realm
public Realm getCustomRealm(Context context) {
if (!Utils.isStringHasText(databaseName)) {
databaseName = DbManager.getInstance().getCurrentDb();
}
// get config
RealmConfiguration config = getRealmConfigByDBName(context, databaseName);
Realm.compactRealm(config);
return Realm.getInstance(config);
}
问题2:现在,在我的应用程序中,我们考虑两种实现方式.
1:每次需要使用数据库(在工作线程和UI线程中)进行操作时,我们都会创建一个新的Realm实例,并在任务完成时将其关闭.
2:我们仅创建一个Realm实例并将其与应用程序一起使用,当退出应用程序时,我们将关闭上面的实例.
请向我解释每种方法的优缺点以及推荐的方法(我的应用程序使用Service处理数据库和网络连接)
如果我有2个繁重的任务(需要很长时间才能完成它的事务),那么由一个Realm实例执行2个任务和在2个单独的线程中的2个Realm实例上执行2个任务之间的区别是什么(我的意思是一个线程有一个Realm实例,实例将执行上述任务中的2分之一),如果更安全,更快捷,则执行其中一项.
如果在执行事务时出现问题(例如不响应或引发某些异常)会发生什么
解决方法:
注意:我不是Realm的正式人士,但是我已经使用Realm已有一段时间了.
这是一个TL;DR version
1.)值得注意的几件事:
>在整个应用程序中,只能使用相同的RealmConfiguration访问给定的Realm文件,因此这里的第一个解决方案是更可取的(不要为每个Realm创建新的配置).
> Realm.compactRealm(RealmConfig)仅在任何线程上都没有打开的Realm实例时起作用.因此,无论是在应用程序启动时,还是在应用程序完成时(我个人而言,我发现启动都会变慢,所以当我的活动计数达到0时我会调用compactRealm(),我使用与活动绑定的保留片段来进行管理-但这仅仅是我).
2)值得注意的是,第一次调用Realm.getInstance()会创建一个线程本地缓存(该缓存在属于同一线程的Realm实例之间共享,并增加一个计数器以指示在该实例上打开了多少个Realm实例.当在所有实例上调用realm.close()导致该计数器达到0时,将清除缓存.
还值得注意的是,Realm实例是线程限制的,因此您将需要在使用它的任何线程上打开一个新的Realm.这意味着,如果在IntentService中使用它,则需要打开一个新的Realm(因为它在后台线程中).
在后台线程上打开的Realm实例上调用realm.close()非常重要.
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
//do database operations
} finally {
if(realm != null) {
realm.close();
}
}
或API 19:
try(Realm realm = Realm.getDefaultInstance()) {
//do database operations
}
>在特定的Realm实例上调用realm.close()时,它将使结果和属于该Realm的对象无效.因此,有必要在Activity onCreate()和onDestroy()中打开/关闭领域,或者在Application中打开它并共享相同的UI线程Realm实例,以便在UI线程上进行查询.
>(在UI线程上关闭Realm实例并不是很重要,除非您打算在所有线程都关闭后对其进行压缩,但是必须在后台线程上关闭Realm实例.)
注意:如果您在Application.onCreate()中调用RealmConfiguration = new RealmConfiguration.Builder(appContext).build(),则在某些设备上调用可能会失败,因为getFilesDir()可以返回null,因此最好仅在之后初始化RealmConfiguration.第一次活动已经开始.
考虑到所有这些,对2)的答案是:
>虽然我个人为UI线程创建了一个Realm实例,但是您仍然需要为所有后台线程打开(并关闭!)新的Realm实例.
>我将Realm的单个实例用于UI线程,因为这样更容易注入,并且还因为如果底层Realm实例仍在执行时关闭了,则executeTransactionAsync()的RealmAsyncTask被取消,所以我不是真的想要那要发生.