LiveData List doesn't update when updating database

筅森魡賤 提交于 2019-12-06 06:52:31

Ok, so I found the solution, although I don't know, why it behaves that way.

Remember when I said "don't worry about the synchronize method"? Well... turns out there were a couple of things wrong with it, which delayed the solution further.

I think the most important error there was the method to update the objects in the database when the network response came in. I used to call

@Update
void update(Form form)

in the dao, which for unknown reasons doesn't trigger the LiveData-Observer. So I changed it to

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

After doing this I could get the Form-LiveData from my repository as easy as

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

Then subscribe to it as usual. The previously failed test looks like this now:

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

I know that exactly 19 Forms will get fetched from the server and then every Form will get changed once (first time I load a list containing all Forms with reduced data, and the second time I load every item from the server again replacing the old value in the db with the new value with more data).

I don't know if this will help you @joao86 but maybe you have a similar issue. If so, please make sure to comment here :)

I had a similar issue with yours --> LiveData is not updating its value after first call

Instead of using LiveData use MutableLiveData and pass the MutableLiveData<List<Form>> object to the Repository and do setValue or postValue of the new content of the list.

From my experience with this, which is not much, apparently the observer is connected to object you first assign it too, and every change must be done to that object.

You have to use the same database instance at all places.

=> Use a singleton for that

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!