Обратите внимание на то, чтобы избегать ям: LiveData «незаметна» и может вызвать проблемы (советы)

PostValue () отбросит старое значение

Однажды, когда я писал логику, я использовал LiveData для передачи таких данных:

textLiveData.postValue("1")
textLiveData.postValue("2")

В результате при обратном вызове было отозвано только «2», так что куда делось «1»!

Взгляните на исходный код postValue:

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
                // 如果 mPendingData 已经有值,postTask 为 false,
            // 就不会执行下面的 postToMainThread 任务
            postTask = mPendingData == NOT_SET;
            
            // 每次 post 这里的 mPendingData 都会刷新,
            // 所以我们总是能得到最新值的回调
            mPendingData = value;
        }

        if (!postTask) {
            return;
        }
        
        // 将任务 post 到主线程 Handler 执行
                ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                    // 设置值之后将  mPendingData 重置
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            // 最终还是调的 setValue
            setValue((T) newValue);
        }
    };

postValue - это отправить значение в основной поток для выполнения, а наш основной поток принимает сообщения в очереди и обрабатывает их одно за другим, поэтому обработка не будет столь своевременной. Проанализируйте сценарий выше, первый пост из «1» на данный момент mPendingData = "1", postTask = trueэта задача - разместить основной поток, ожидающий выполнения. Тогда после «2». В это время mPendingData = "2", postTask = falseтолько значение mPendingData будет изменено, а задача главного потока будет выполняться после того, как mPendingData изменяется на «2». Таким образом, обратный вызов, который мы получаем, всегда остается последним.

Резюме : postValue на самом деле разработан для многопоточных сред, его не нужно использовать в обычных сценариях. Просто используйте setValue напрямую.

Обратные вызовы LiveData, вызванные повторяющимися обратными вызовами в жизненном цикле

Раньше я использовал LiveData для передачи событий щелчка между Activity и Fragment. При использовании во фрагменте в ViewPager он взорвется.При переключении фрагмента влево и вправо запускается событие щелчка.

Поскольку LiveData всегда возвращается, чтобы проверить, есть ли значение, когда компонент инициализирован и активен, он обратится, если есть значение. Таким образом, если фрагмент зарегистрирован с помощью обратного вызова LiveData, а действие многократно удаляется, а затем добавляется к фрагменту, он будет вызывать несколько обратных вызовов LiveData. (Примечание: LiveData здесь существует в ViewModel Activity, и его жизненный цикл длиннее, чем у фрагмента)

Мое предыдущее решение заключалось в том, чтобы установить для LivaData значение null во время фрагмента onDestory. На самом деле это недостаточно элегантно, это вид краткосрочных новостей, бессмысленно инкапсулировать LiveData:

После отправки сообщения оно сразу становится пустым, и значение мимолетных LiveData не сохраняется. Здесь вам нужно хорошо оценить null:if(v == null) return

class FleetingLiveData<T> : MutableLiveData<T>() {

    override fun setValue(value: T) {
        super.setValue(value)
        super.setValue(null)
    }

    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
        super.observe(owner, Observer {
            if (it == null) return@Observer
            observer.onChanged(it)
        })
    }
}

Резюме : LiveData привязана к жизненному циклу компонента, и функция, которая будет вызываться при наличии значения, имеет преимущества и недостатки. Его можно использовать для закрепленных событий, но если он не используется должным образом, будут возникать странные обратные вызовы, такие как использование для доставки событий щелчка, таких как краткосрочные события, для которых не нужно сохранять значения.


Прочитав лайки, выработайте привычку, поищите в WeChat «Центр разработки программных обезьян», чтобы следить за этим программистом, который любит писать сухие товары.

Кроме того, есть также полный тестовый сайт для интервью с крупными компаниями, занимающимися Android первой линией. Информация обновляется в моем Gitee . Друзья, которым нужны интервью, могут ссылаться на них. Если это будет полезно для вас, вы можете заказать звезду!

Адрес Gitee : [ Old Chen’s Gitee ]


 

рекомендация

отblog.csdn.net/qq_39477770/article/details/108851836