簡體   English   中英

更新數據庫時,LiveData List不會更新

[英]LiveData List doesn't update when updating database

我目前正在重構遺留代碼以使用Android架構組件,並在一種存儲庫模式中設置房間數據庫和排球請求。 因此,表示/域層要求存儲庫獲取LiveData-Objects以觀察或告訴他與服務器同步,之后刪除舊的db條目並從服務器重新獲取所有當前的條目。

我已經為同步部分編寫了測試,所以我確信,對象會被正確獲取並插入到數據庫中。 但是當編寫一個測試來觀察那個db表的條目時(並測試對象是否正確保存了所有需要在將它們放入db之前完成的)LiveData>我正在觀察,不會被觸發。

在下面的代碼片段中,您可以假設,synchronizeFormsWithServer(...)方法可以正常工作,並且異步執行數據庫操作。 它包含從db中刪除所有Form-Objects的操作,這些操作從服務器獲取的Forms列表中不存在並插入所有新的Form-Objects。 因為在測試開始時數據庫是空的,所以這應該不重要

觀察者未被觸發的測試:

  @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());
   }

FormRepository代碼:

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

數據存儲區:

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

formDao代碼(數據庫實現了你從房間里期待它的方式):

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

很可能,我對LiveData-Components沒有任何了解,因為這是我第一次使用它們,所以也許我得到了一些根本錯誤的東西。

非常感謝每一點幫助:)

PS:我偶然發現了這篇文章,討論了類似的問題,但由於我現在根本沒有使用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是否有幫助,但也許你有類似的問題。 如果是這樣,請務必在這里發表評論:)

我和你的問題有類似的問題 - > LiveData在第一次調用后沒有更新它的值

而不是使用LiveData使用MutableLiveData並將MutableLiveData<List<Form>>對象傳遞給Repository並執行列表新內容的setValuepostValue

根據我對此的經驗,這並不多,顯然觀察者已經連接到對象,你首先分配它,並且必須對該對象進行每個更改。

您必須在所有位置使用相同的數據庫實例。

=>使用單例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM