Android LiveData: не все уведомления

Я экспериментирую с LiveData Android. Я просто попытался отправить множество уведомлений наблюдателю, который наблюдает за объектом LiveData. Я позволяю потоку работать в фоновом режиме, а в цикле while я постоянно добавляю случайные значения с помощью метода postValue LiveData. Количество полученных уведомлений (количество onChanged () - обратных вызовов) в наблюдателе, который наблюдает за живыми данными, намного меньше, чем количество вызовов postValue в фоновом потоке.

Может кто-нибудь объяснить, в чем причина этого?

заранее спасибо


person MarcWho    schedule 25.06.2018    source источник
comment
Я пробовал разные интервалы сна между сообщениями. поскольку я пытаюсь проверить, как мое приложение реагирует на большое количество данных, я позволяю thead спать на наносекунду между   -  person MarcWho    schedule 25.06.2018
comment
ты получил решение своей проблемы? У меня аналогичная проблема.   -  person venimania    schedule 02.01.2019
comment
Нет. Я попытался провести стресс-тест, в котором увеличил количество push-уведомлений. Оказалось, что механизм класса LiveData повысил надежность моей программы, поэтому я не пытался изменить поведение класса LiveData.   -  person MarcWho    schedule 05.01.2019


Ответы (1)


Объяснение заключается в реализации для postValue и mPostValueRunnable:

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        //this is true on the first run or right after the observer receives an update
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    // this statement will be true if the observer hasn't received an update even though it's sent to the main looper
    if (!postTask) { 
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;//once this value is reset a new mPostValueRunnable can be sent
        }
        // here the observer will receive the update
        setValue((T) newValue);
    }
};  
  1. При первом запуске в postValue mPendingData = NOT_SET, поэтому следующее if (!postTask) условие - false и, таким образом, mPostValueRunnable отправляется в основной поток.
  2. Во втором прогоне, если mPostValueRunnable еще не был выполнен (это может не быть, поскольку значения обновляются очень часто), if будет true, и поэтому в основной поток ничего не отправляется, кроме того, что mPendingData устанавливается на новое значение.
  3. При третьем запуске он может быть таким же, как и при предыдущем, и так далее для некоторого количества обновлений. Таким образом, пока mPostValueRunnable не запустится и не сбросит mPendingData на NOT_SET, все значения обновления будут потеряны, кроме последнего. В этом случае через Observer поступает только одно обновление с последним значением.
person Anatolii    schedule 25.06.2018