ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-更深入地了解Realm的工作原理?

2019-10-26 21:03:30  阅读:505  来源: 互联网

标签:realm java android


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被取消,所以我不是真的想要那要发生.

标签:realm,java,android
来源: https://codeday.me/bug/20191026/1939419.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有