如何修复:Room DAO LiveData在快速后台启动并恢复应用程序后停止在整个应用程序中发出

时间:2019-07-02 21:49:03

标签: android android-room android-livedata

我有几个ViewModel,它们通过Room DAO创建的LiveData对象上创建观察者。这些ViewModel将各种LiveData发射合并为最终的ViewState LiveData,这些状态将通过各自的Fragment进行观察。这些通常都可以正常工作,但是在某些情况下,几乎所有连接到Room的LiveData都会突然中断。

如果我打开我的应用程序,从应用程序中快速点击“返回”,然后快速恢复该应用程序,则大多数以任何方式与Room交互的LiveData链都有5-10%的机会永久停止,就像没有观察到LiveData链。这种情况在应用程序的任何地方都会发生,甚至在表现出病理行为之前我在当前会话中未曾访问过的片段上也会发生。

深入研究代码后,一旦达到错误状态,似乎从未调用过Callable传递到Room的失效跟踪器。作为实验,我在profileStream上创建了一个watchForever以查看是否可以使用其他代码路径。这导致Callable被执行,但是它返回陈旧的数据。无论如何,ObserveForever是一个不合适的解决方案,我不想进一步调试此选项。

由于怀疑与生命周期相关的问题,我在对Fragments的viewLifecycleOwners的观察调用中交换了“ this”。这似乎并没有改变任何东西。

    public void  productName(String productName) { 
        try {
            for(int i = 1; i < productName.length(); i++) { 
        }       
    }
        catch(Exception e) {
            System.out.println("Please enter a product name ");         
        }
    }

    public void storeName(String storeName) {
        try {
            for(int i = 1; i < storeName.length(); i++) { 
        }       
    }
        catch(Exception e) {
            System.out.println("Please enter a store name");
        }
    }

    public void purchaseDate(String date) {
        DateTimeFormatter format = DateTimeFormatter.ofPattern(date);
        try {
            format.parse(date);
        }
        catch(Exception e) {
            System.out.println("Invalid date");
        }
    }

    public void cost(double newCost) 
         throws InputMismatchException{
        double cost;
        if(newCost >= 1)
            cost = newCost;
        else 
            throw new InputMismatchException("Cost must be a integer and more the $0 ");
    }
viewModel.viewState.observe(viewLifecycleOwner, Observer { render(it) })
VIEWMODEL

init {
  val profileStream = profileRepo.getProfile(id)
  viewState.addSource(mapPhotoStream()) { photos -> viewState.value = 
  currentViewState().copy(photos = photos) }

  viewState.addSource(profileStream) { profile ->
    if (profile.name == null) {
      Log.w(TAG, "Name of a profile should not be null. 
      UserId=${profile.userId}")
    }
    viewState.value = currentViewState().copy(
      name = profile.name ?: ""
    )
  }
}

0 个答案:

没有答案