MediatorLiveData.getValue()。isEmpty()直接删除后返回false

问题描述 投票:0回答:1

我怎么能检查一个表是否为空,因为知道我没有保证或同步返回值的活动?

嘿伙计们,我是建筑组件的新手。我对MediatorLiveData有一个非常奇怪的问题..我需要做的就是使用后台服务“AlarmManager”和postValue(null)删除Room Entity中的所有值到MediatorLiveData,然后我需要调用refreshTables()来检查是否表中没有数据,它调用Web服务并插入值。

一切正常但是当我在删除后看到调用refreshTables()时,有时条件getValue()。isEmpty()返回false !!

当这件事发生时,它会使表没有数据。

我相信MediatorLiveData观察有一个延迟。

笔记:

1-删除后,我在一个线程(执行程序)中调用refreshTables(),当然,refreshTables()使用其执行程序执行。

2-这种故障几乎每20次工作正常。

3-我试图覆盖onChange但抛出异常是因为它无法将LiveData强制转换为LifeCycleOwner

4- TableEntity只是一个Room Entity包含有关餐厅表的字段

 //the constructor
  private DataRepository(AppDatabase database
 ) {
     this.mDatabase = database;
     executor = new AppExecutors();


     mObserableTables = new MediatorLiveData<>();

              mObserableTables.addSource(mDatabase.tableDao().loadAllTables(),
             tableEntities -> {
                 if (mDatabase.getDatabaseCreated().getValue() != null)
                     mObserableTables.postValue(tableEntities);
             });
 }    

  private MediatorLiveData<List<TableEntity>> mObserableTables;

public void refereshTables()
{

    executor.networkIO().execute(()->
    {
        try {
            if(mObserableTables.getValue()==null || mObserableTables.getValue().isEmpty()) {//<-the problem

                List<TableEntity> tableEntities = new WebserviceCall().getTablesOnline();
                mDatabase.tableDao().insertOrReplaceAllTables(tableEntities);
            }
        }catch (IOException e)
        {
            Log.d(this.getClass().getName(),e.getMessage());

        }
    });
}

 public void refreshTablesForService()
{
    executor.diskIO().execute(()->
    {

            int deletedRows=mDatabase.tableDao().deleteAllTables();
            Log.d(this.getClass().getName()
                    ,"deleted rows from tables= "+String.valueOf(deletedRows));

            mObserableTables.postValue(null);
                refereshTables();


    });
}
java android mvvm android-room android-architecture-components
1个回答
0
投票

回答我自己的问题:)

经过几个小时的深挖,我发现getValue()没什么可做的。问题出在.postValue()方法中,它使用UiThread将值放在LiveData中。这肯定需要向UI添加一个可能被延迟的任务,并在完成此任务之前检查数据会导致不一致。

甚至试图从表中加载所有数据都提供了不一致的信息。试图removeSource()也不会对这个问题做任何事情。

我设法通过使用“SELECT COUNT(*)FROM tables”查询来处理此问题,该查询为我提供了准确的信息。

顺便说一句,在调用refereshTables()之前添加“Thread.sleep(100)”;修复问题,但给用户带来非常糟糕的体验。

一个奇妙的解释让我想出来的是https://code.tutsplus.com/tutorials/android-architecture-component-livedata--cms-29317

© www.soinside.com 2019 - 2024. All rights reserved.