Java 更深入地了解领域是如何运作的?
Q1:请让我知道下面两种Java 更深入地了解领域是如何运作的?,java,android,realm,Java,Android,Realm,Q1:请让我知道下面两种实现方法的不同之处(关于get领域实例)。我想知道哪一个更快,内存更轻,推荐什么 1。设置并获取领域作为默认值(使用特定配置) 2.直接从配置中获取领域 public Realm getCustomRealm(Context context) { if (!Utils.isStringHasText(databaseName)) { databaseName = DbManager.getInstance().getCurrentD
实现方法的不同之处(关于get领域实例
)。我想知道哪一个更快,内存更轻,推荐什么
1。设置并获取领域作为默认值(使用特定配置)
2.直接从配置中获取领域
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);
}
<强> q2:在我的应用程序中,现在我们考虑2种实现方式。
1:每当我们需要处理数据库时(在工作线程和UI线程中),我们都会创建一个新的领域实例,并在任务完成时关闭它
2:我们只创建一个Realm实例,让它和应用程序一起使用,当退出应用程序时,我们关闭上面的实例
请解释每种方法的优缺点以及推荐的方法(我的应用程序使用服务处理数据库和网络连接)
如果我有两个繁重的任务(需要很长时间才能完成它的事务),那么一个领域实例执行2个任务和在两个独立线程中的两个领域实例上执行2个任务之间有什么区别(我的意思是一个线程有一个领域实例,实例将执行上面2个任务中的一个),以及哪一个更安全、更快
如果在执行事务时出现问题(例如没有响应或抛出一些异常),会发生什么情况?注意:我不是正式的领域人员,但我已经使用领域一段时间了
这里有一个
1.)值得注意的是:
- 在整个应用程序中,只能使用相同的
RealmConfiguration
访问给定的领域文件,因此这里的第一个解决方案更可取(不要为每个领域创建新配置)
Realm.compactRealm(RealmConfig)
仅当任何线程上没有打开的领域实例时才起作用。因此,无论是在应用程序启动时,还是在应用程序完成时(我个人发现这会使启动速度变慢,所以当我的活动计数达到0
时,我调用compactRealm()
,我使用绑定到活动的保留片段来管理它-但这只是我自己)
2.)值得注意的是,第一次调用时,Realm.getInstance()
会创建线程本地缓存(缓存在属于同一线程的领域实例之间共享,并递增一个计数器,以指示给定线程上打开的领域实例的数量。在所有实例上调用Realm.close()
后,当该计数器达到0
时,缓存被清除
还值得注意的是,领域
实例是线程限制的,因此您需要在使用它的任何线程上打开一个新的领域
。这意味着如果您在IntentService中使用它,您需要打开一个新领域(因为它位于后台线程中)
在后台线程上打开的领域实例上调用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.close()
时,它会使属于它的结果和对象无效。因此,在活动onCreate()
和onDestroy()中打开/关闭领域都是有意义的
,或者在应用程序中打开它并共享同一UI线程领域实例,以便在UI线程上进行查询
- (在UI线程上关闭领域实例并不重要,除非您打算在所有领域实例都关闭后对其进行压缩,但您必须在后台线程上关闭领域实例。)
注意:调用RealmConfiguration RealmConfiguration=new RealmConfiguration.Builder(appContext).build()
如果在Application.onCreate()
中调用,可能会在某些设备上失败,因为getFilesDir()
可以返回null
,因此最好仅在第一个活动启动后初始化RealmConfiguration
考虑到所有这些,2)的答案是:
- 虽然我个人为UI线程创建了一个Realm实例,但您仍然需要为任何后台线程打开(并关闭!)一个新的Realm实例
- 我将Realm的一个实例用于UI线程,因为这样更容易注入,而且还因为
executeTransactionAsync()
- 别忘了,UI线程上需要一个Realm实例来显示来自Realm查询的
RealmResults
(除非您打算使用copyFromRealm()
,这会使所有内容占用更多内存,而且通常速度较慢)
IntentService
的工作方式与普通后台线程类似,因此您也应该关闭那里的realm实例
无论是同一个领域实例还是另一个领域实例,这两个繁重的任务都可以工作(只需确保给定线程上有一个领域实例),但我建议依次连续执行这些任务
如果在事务处理过程中出现异常,您应该调用realm.cancelTransaction()
(文档称为begin/commit,但它总是忘记cancel)
如果不想手动管理begin/commit/cancel,应该使用realm.executeTransaction(new realm.Transaction(){…})代码>,因为它会自动为您调用begin/commit/cancel。就我个人而言,我在任何地方都使用executeTransaction()
,因为这很方便。吃完午饭后我会回答这个问题(回复钩子评论)太好了!我在等你的回答!我还链接了SO Realm文档,因为它们很整洁,我保持了一些最新的内容:我还提供了一个sh
try(Realm realm = Realm.getDefaultInstance()) {
//do database operations
}