Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 更深入地了解领域是如何运作的?_Java_Android_Realm - Fatal编程技术网

Java 更深入地了解领域是如何运作的?

Java 更深入地了解领域是如何运作的?,java,android,realm,Java,Android,Realm,Q1:请让我知道下面两种实现方法的不同之处(关于get领域实例)。我想知道哪一个更快,内存更轻,推荐什么 1。设置并获取领域作为默认值(使用特定配置) 2.直接从配置中获取领域 public Realm getCustomRealm(Context context) { if (!Utils.isStringHasText(databaseName)) { databaseName = DbManager.getInstance().getCurrentD

Q1:请让我知道下面两种
实现方法的不同之处(关于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
}