更新数据库时 LiveData 列表不更新

2024-04-25

我目前正在重构遗留代码以使用 Android 架构组件,并在一种存储库模式中设置房间数据库和齐射请求。 因此,表示/域层要求存储库获取 LiveData-Objects 来观察或告诉他与服务器同步,然后删除旧的数据库条目并从服务器重新获取所有当前的数据库条目。

我已经为同步部分编写了测试,因此我确信对象已正确获取并插入到数据库中。但是,当编写测试来观察该数据库表的条目(并测试对象是否正确保存以及将它们放入数据库之前需要完成的所有操作)时,我正在观察的 LiveData> 不会被触发。

在下面的代码片段中,您可以假设,synchronizeFormsWithServer(...) 方法确实工作正常并且正在异步执行数据库操作。它包含从数据库中删除所有不存在于从服务器获取的表单列表中的表单对象的操作,并插入所有新的表单对象。由于在测试开始时数据库是空的,这应该不重要

观察者不被触发的测试:

  @Test
  public void shouldSaveFormsFromServerIntoDb() throws Exception
   {
    Lifecycle lifecycle = Mockito.mock(Lifecycle.class);
    when(lifecycle.getCurrentState()).thenReturn(Lifecycle.State.RESUMED);
    LifecycleOwner owner = Mockito.mock(LifecycleOwner.class);
    when(owner.getLifecycle()).thenReturn(lifecycle);

    final CountDownLatch l = new CountDownLatch(19);

    formRepository.allForms().observe(owner, formList ->
    {
     if (formList != null && formList.isEmpty())
      {
       for (Form form : formList)
        {
         testForm(form);
         l.countDown();
        }
      }
    });

    formRepository.synchronizeFormsWithServer(owner);
    l.await(2, TimeUnit.MINUTES);
    assertEquals(0, l.getCount());
   }

表单存储库代码:

  @Override
  public LiveData<List<Form>> allForms()
   {
    return formDatastore.getAllForms();
   }

数据存储:

  @Override
  public LiveData<List<Form>> getAllForms()
   {
    return database.formDao().getAllForms();
   }

formDao 代码(数据库按照您期望的 Room 实现方式实现):

  @Query("SELECT * FROM form")
  LiveData<List<Form>> getAllForms();

很可能我对 LiveData 组件不了解,因为这是我第一次使用它们,所以也许我犯了一些根本性的错误。

非常感谢您的每一点帮助:)

PS:我偶然发现THIS https://stackoverflow.com/questions/44742445/room-livedata-observer-does-not-trigger-when-database-is-updated帖子,其中讨论了类似的问题,但由于我目前根本不使用 DI,而只使用 formrepository 的单个实例(它只有一个关联的 formDao 实例),我认为这不是同一个问题。


好的,所以我找到了解决方案,尽管我不知道为什么会这样。

还记得我说过“不要担心同步方法”吗?嗯...事实证明它有一些问题,这进一步延迟了解决方案。

我认为最重要的错误是当网络响应到来时更新数据库中的对象的方法。 我以前打电话

@Update
void update(Form form)

在 dao 中,由于未知原因,它不会触发 LiveData-Observer。所以我把它改为

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Form form);

完成此操作后,我可以从我的存储库中获取 Form-LiveData,就像

LiveData<List<Form>> liveData = formRepository.allForms();

然后像往常一样订阅它。 之前失败的测试现在看起来像这样:

  @Test
  public void shouldSaveFormsFromServerIntoDb() throws Exception
   {
    Lifecycle lifecycle = Mockito.mock(Lifecycle.class);
    when(lifecycle.getCurrentState()).thenReturn(Lifecycle.State.RESUMED);
    LifecycleOwner owner = Mockito.mock(LifecycleOwner.class);
    when(owner.getLifecycle()).thenReturn(lifecycle);

    final CountDownLatch l = new CountDownLatch(19);

    final SortedList<Form> sortedForms = new SortedList<Form>(Form.class, new SortedList.Callback<Form>()
     {
      @Override
      public int compare(Form o1, Form o2)
       {
        return o1.getUniqueId().compareTo(o2.getUniqueId());
       }


      @Override
      public void onChanged(int position, int count)
       {
        Log.d(LOG_TAG, "onChanged: Form at position " + position + " has changed. Count is " + count);
        for (int i = 0; i < count; i++)
         {
          l.countDown();
         }
       }


      @Override
      public boolean areContentsTheSame(Form oldItem, Form newItem)
       {
        return (oldItem.getContent() != null && newItem.getContent() != null && oldItem.getContent().equals(newItem.getContent())) || oldItem.getContent() == null && newItem.getContent() == null;
       }


      @Override
      public boolean areItemsTheSame(Form item1, Form item2)
       {
        return item1.getUniqueId().equals(item2.getUniqueId());
       }


      @Override
      public void onInserted(int position, int count)
       {

       }


      @Override
      public void onRemoved(int position, int count)
       {

       }


      @Override
      public void onMoved(int fromPosition, int toPosition)
       {

       }
     });

    LiveData<List<Form>> ld = formRepository.allForms();
    ld.observe(owner, formList ->
    {
     if (formList != null && !formList.isEmpty())
      {
       Log.d(LOG_TAG, "shouldSaveFormsFromServerIntoDb: List contains " + sortedForms.size() + " Forms");
       sortedForms.addAll(formList);
      }
    });

    formRepository.synchronizeFormsWithServer(owner);
    l.await(2, TimeUnit.MINUTES);
    assertEquals(0, l.getCount());
   }

我知道将从服务器获取 19 个表单,然后每个表单都会更改一次(第一次加载包含所有数据减少的表单的列表,第二次我再次从服务器加载每个项目,替换旧值)在数据库中具有更多数据的新值)。

我不知道这是否会对您有帮助@joao86,但也许您有类似的问题。如果是这样,请务必在这里发表评论:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更新数据库时 LiveData 列表不更新 的相关文章

  • 如何在Jenkins上更改工作空间并建立记录根目录?

    我希望将 Jenkins 的数据写入驱动器 E 因为这是服务器上的大型驱动器 Jenkins 本身安装在 C 上 我怎么做 我看到的默认配置是 工作区根目录 ITEM ROOTDIR 工作区 构建记录根目录 ITEM ROOTDIR 构建
  • 在 selenium webdriver 中打开一个新窗口而不是新选项卡

    当在我的应用程序中手动单击链接时 它会在 Chrome 和 IE 中的新选项卡中打开 但是 当我的脚本运行时 该链接会在 IE 中的新窗口而不是新选项卡中打开 相同的脚本在 Chrome 中按预期运行 知道如何摆脱这个吗 更改 IE 的默认
  • 以 UTF8 而不是 UTF16 输出 DataTable XML

    我有一个 DataTable 我正在使用 WriteXML 创建一个 XML 文件 尽管我在以 UTF 16 编码导出它时遇到问题 并且似乎没有明显的方法来更改它 我了解 NET 在字符串内部使用 UTF 16 这是正确的吗 然后 我通过
  • 错误:模块“html”不提供视图引擎(Express)

    我正在尝试设置一个简单的路由应用程序 但在渲染页面时不断遇到错误 Error Module html does not provide a view engine 奇怪的是我已经在 app js 文件中指定了视图引擎 但仍然收到错误 app
  • Maven 构建错误 TOOLS.JAR NOT FOUND IN JRE

    我在构建 Maven 项目时遇到这个问题 请帮我解决 ERROR Failed to execute goal org apache maven plugins maven compiler plugin 2 5 1 compile def
  • Android 的代码覆盖率[重复]

    这个问题在这里已经有答案了 可能的重复 Android测试代码覆盖率 Eclipse https stackoverflow com questions 3282702 android test code coverage eclipse
  • 关闭扫描仪是否会影响性能

    我正在解决一个竞争问题 在问题中 我正在使用扫描仪获取用户输入 这是 2 个代码段 一个关闭扫描器 一个不关闭扫描器 关闭扫描仪 import java util Scanner public class JImSelection publ
  • UWP 应用程序在与商店关联后崩溃

    我正在为 Windows 创建一个 cordova 应用程序 将应用程序与商店关联后 应用程序起始页变为白色空白 如果应用程序使用包标识名称 com something moretext 则该应用程序可以正常工作 但我的商店包身份名称是 5
  • Swift 中的 quitFirstResponder

    我怎样才能用Apple的新语言实现它 Objective C 代码 void touchesBegan NSSet touches withEvent UIEvent event for UIView view in self view s
  • Maven2继承

    如果我有一个父 pom 并且想将其继承到多个项目 我通常通过添加到项目顶部来做到这一点
  • 纯旧 PHP 对象 (POPO) 一词的确切含义是什么?

    我想了解一下波波 我搜索了 popo 发现它代表 Plain Old Php Object 但我不确定 Plain Old Php Object 的确切含义 我想知道什么是 popo 以及在哪里使用它 谢谢 普通旧 在此处插入语言 对象是一
  • 文本处理问题:删除其中一列不包含特定值的行

    我有一个制表符分隔的文件 如下所示 input sequence match sequence score receptor group epitope antigen organism ASRPPGGVNEQF ASRPPGGVNEQF
  • 如何用LoaderManager自动重新查询

    我有一个应用程序显示来自 SQLite DB 的数据 并且数据不断变化 所以显然 我认为我应该使用 LoaderManager 来显示数据 我读过一些关于将 LoaderManager 与 SQLite 结合使用的内容 然后看到了亚历克斯
  • 用 Beautiful Soup 进行抓取:为什么 get_text 方法不返回该元素的文本?

    最近我一直在用 python 开发一个项目 其中涉及抓取一些网站的一些代理 我遇到的问题是 当我尝试抓取某个知名代理站点时 当我要求 Beautiful Soup 查找 IP 在代理表中的位置时 它并没有按照我的预期执行操作 我将尝试查找每
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne
  • 使用并非为 IOC 设计的遗留应用程序避免服务定位器反模式

    我经常读到IOC 中的服务定位器是一种反模式 http blog ploeh dk 2010 02 03 ServiceLocatorIsAnAntiPattern aspx 去年 我们在工作中的应用程序中引入了 IOC 具体来说是 Nin
  • 从 Teradata sql Assistant 将结果导出到 Excel 工作表

    我想通过在 Teradata SQL Assistant 中运行查询将结果导出到 Excel 工作表中 我使用了复制粘贴 但没有用 提前致谢 如果您将答案返回到 SQL Assistant 您应该能够从 文件 菜单中选择 保存答案集 然后
  • 将 read.csv 与符号链接文件一起使用

    我正在尝试做什么 我的源文件非常大 我想避免将其复制到其他文件夹中 我决定创建一个指向大文件的符号链接并想使用read csv读取文件 文件夹结构 项目1 数据 源文件 csv 项目2 数据 别名到源文件 csv 什么地方出了错 读取源文件
  • 为什么 FMA _mm256_fmadd_pd() 内在函数有 3 个 asm 助记符:“vfmadd132pd”、“231”和“213”?

    有人可以向我解释一下为什么融合乘法累加指令有 3 种变体 vfmadd132pd vfmadd231pd and vfmadd213pd 而只有一个 C 内在函数 mm256 fmadd pd 为了简单起见 在 AT T 语法中 有什么区别
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐

  • Google Chrome 中 array.splice() 的时间复杂度是多少?

    如果我使用 splice 从数组中删除一个元素 如下所示 arr splice i 1 这会是O n 在最坏的情况下 因为它会移动 i 之后的所有元素 或者它是常数时间 下面有一些链表魔法 最坏的情况下should be O n 复制所有n
  • .NET:属性何时实例化?我可以获得它们所修饰的类型的引用吗?

    关于属性的两个问题 属性类什么时候实例化 当第一次访问类型时 还是在开始执行时 从属性类中 我可以找出该属性是为哪种类型实例化的吗 我的想法是 我想列出程序集中应用了我的属性的所有类的列表 我当然可以通过反射和检查来迭代所有这些 但如果该属
  • r中的模糊字符串匹配

    我有 2 个数据集 每个数据集超过 100K 行 我想根据匹配一列 电影标题 的模糊字符串以及使用发布日期来合并它们 我提供了下面两个数据集中的样本 数据集 1 itemid userid rating time title release
  • 更改 UISearchBar 的大小

    无法找到答案 也无法做我想做的事 CGSize searchBarSize self searchDisplayController searchBar frame size searchBarSize width
  • 如何使用 URLSession 从 url 获取 JSON 数据?

    我正在开发一个 iOS 应用程序 我必须从中获取数据this url https dl dropboxusercontent com s 2iodh4vg0eortkl facts json 我可以看到这个 url 包含 JSON 数据 所
  • Android FloatingActionButton 带有片段和底部导航栏

    我正在创建一个具有以下结构的 Android 应用程序 主要活动有一个底部导航栏 可在 3 个不同的片段之间切换 其中 2 个片段将显示项目列表 并使用浮动操作按钮 FAB 添加新项目 第三个片段将显示不同的内容 不需要 FAB 基于此 F
  • 使用 gradle 进行简单的 protobuf 编译

    如果您正在寻找示例 gradle protobuf 项目 请查看here https github com google protobuf gradle plugin tree master examples exampleProject
  • “没有路线匹配”错误?

    我是新的 Rspec 刚刚开始在 Rails 3 上生成一个新的控制器 它默认生成一些 Rspec 测试 我有一个关于如何让它们通过的问题 就目前情况而言 我在我的终端中看到了这个测试 1 BuildingsController GET s
  • 将数据写入文本文件

    我有一个简单的程序 将 7 个数字中的 6 个写入文本文件 从逻辑上讲 一切似乎都很好 但是 数字并未按预期写入文件 Random random new Random Console WriteLine Please enter the n
  • 将 json 数据 objectForKey 分配给类的属性的替代语法

    我可以将最后三行代码写在一行中吗 NSArray latestLoans self JsonData objectForKey loans for id object in latestLoans NSDictionary loan obj
  • 使用 Testcafe 访问 OpenVPN 限制的网站

    有一个网站只有在运行 OpenVPN Connect 2 1 3 111 配置文件时才能访问 我需要使用 Testcafe 访问该网站 但到目前为止我还没有找到任何有关使用 Testcafe 与 VPN 的文档 有什么我可能错过的吗 测试通
  • git clone 永远挂在 github 上

    当我按照 github 中的第 5 点 测试所有内容 时guide http help github com linux set up git ssh 命令也永远挂起 根据该指南 我应该看到一条消息 Github 不提供 shell 访问
  • Python 使 UMAP 更快(呃)

    我正在使用 UMAP https umap learn readthedocs io en latest https umap learn readthedocs io en latest 以减少数据的维度 我的数据集包含 4700 个样本
  • Math.min.apply 对于 null 返回 0

    我想从数组中获取最小值 如果数据包含null value Math min apply回报0 for null价值 请参见这个 JSFiddle 示例 http jsfiddle net jeryslo 7DCXw 即使数组中存在空值 如何
  • 使用 DirectSound 向后读取声音

    是否可以使用 DirectSound 的托管版本向后读取声音 如果没有 是否有另一个库可以轻松实现 您可以使用 WaveFileReader 和 WaveFileWriter 类NAudio http www codeplex com na
  • 如何在 python-docx 中将页面大小更改为 A4

    我尝试使用 python docx 创建 Word 文档 创建的文件的字母尺寸为 8 5 x 11 英寸 但在德国 标准格式是 A4 8 27 x 11 69 英寸 from docx import Document from docx s
  • 从工作线程 C# CF 在主线程中抛出事件

    我有 可能是 一个简单的问题 我正在使用互操作来调用 CompactFramework 中的异步函数 获得执行结果后 我想引发一个事件 该事件将被表单捕获 并根据结果 我将在屏幕上呈现一些数据 然而 问题是 当互操作函数返回结果时 它会在工
  • 找出数组中重复的元素

    有一个大小为 n 的数组 数组中包含的元素在 1 到 n 1 之间 每个元素出现一次 只有一个元素出现多次 我们需要找到这个元素 尽管这是一个非常常见的常见问题解答 但我仍然没有找到正确的答案 大多数建议是我应该将数组中的所有元素相加 然后
  • 在 Swift 中将 Int 更改为 CGFloat 以返回 heightForRowAtIndexPath tableview 函数

    我确信我错过了一些非常简单的东西 但我就是无法让它发挥作用 我会尽力更好地解释我正在做的事情 以帮助其他遇到同样问题的人 这是我的职能 func tableView tableView UITableView heightForRowAtI
  • 更新数据库时 LiveData 列表不更新

    我目前正在重构遗留代码以使用 Android 架构组件 并在一种存储库模式中设置房间数据库和齐射请求 因此 表示 域层要求存储库获取 LiveData Objects 来观察或告诉他与服务器同步 然后删除旧的数据库条目并从服务器重新获取所有