为什么LiveData仍会通知处于onPause状态的Activity?

时间:2018-10-02 22:31:27

标签: android android-architecture-components android-livedata

我在Activity中有以下代码

@Override
public void onPause() {
    super.onPause();

    if (isFinishing()) {
        final LiveData<StickyNoteConfig> stickyNoteConfigLiveData = StickyNoteConfigRepository.INSTANCE.getStickyNoteConfig(mAppWidgetId);
        stickyNoteConfigLiveData.removeObservers(this);
        stickyNoteConfigLiveData.observe(this, stickyNoteConfig -> {
            // Weird, I still can receive call back.
            // I thought "this" is no longer active?
        });
    }
}

我感到困惑的是,尽管Observer活动已经处于this状态,但是onPause仍在被触发?根据{{​​3}}

  

LifecycleOwner的开始状态。对于活动,此状态为   有两种情况:

after onStart call;
right before onPause call.

我可以知道为什么会这样吗?

4 个答案:

答案 0 :(得分:9)

  

根据LiveData参考,

     
      
  1. LiveData是可以在给定生命周期内观察到的数据持有者类。这意味着可以在观察者中添加   与LifecycleOwner配对,此观察者将收到有关   仅当成对的LifecycleOwner时才修改包装数据   处于活动状态。 LifecycleOwner被认为是有效的(如果其   状态为 STARTED RESUMED

  2.   
  3. 添加了生命周期的观察者,如果相应的生命周期变为 DESTROYED 状态,则会自动删除。

  4.   

现在,根据您在此处的情况,LiveData将以 onPause() 方法接收观察者(您的活动)的更新,因为尚未处于 DESTROYED 状态。

根据以下方法,LiveData仍处于活动状态以接收更新:

onActive()

当活动观察者的数量从0变为1时调用。 可以使用此回调来知道正在使用此LiveData,因此应保持最新状态。

onInactive()

当活动观察者的数量从1变为0时调用。这并不意味着没有观察者,可能仍然有观察者,但是它们的生命周期状态不是STARTED或RESUMED (例如Activity in后面的堆栈)

您可以通过hasObservers()检查是否有观察员。


那么观察者(您的活动)何时会获得毁灭状态?

对于LifeCycleOwner的默认实现,表示执行 onDestroy() 方法并在 onPause() 之后,活动将其变为DESTROYED状态遵循生命周期状态相反的顺序:<恢复>-已开始->创建->已破坏。

选中此lifecycle graph

希望有帮助!

答案 1 :(得分:2)

https://medium.com/@hanyuliu/livedata-may-lose-data-2fffdac57dc9有日志来解释此问题。就像@Vairavan所说的,在暂停状态下,活动可以部分可见。

公共枚举州{

DESTROYED,

INITIALIZED,

CREATED,

STARTED,

RESUMED;

public boolean isAtLeast(@NonNull State state) {
    return compareTo(state) >= 0;
}

}

因此,观察者的isAlive判断依据isAtLeast(STARTED)。调用OnPause时,活动不会被破坏。

答案 2 :(得分:0)

当onPause和onStop与UI副作用相关时,这变得很明显。如果活动窗口的任何部分仍然可见,则活动将暂停并且不会停止。当另一个活动作为对话框显示在暂停的活动的顶部时,可能会发生这种情况。在这种情况下,开发人员通常希望暂停的活动的UI仍然可以被更新,即使它只是部分可见。在此暂停状态下,LiveData的更新有助于实现这一目标。

还有其他情况,例如多窗口功能。当用户与另一个窗口中的另一个应用程序/活动交互时,一个活动可能会暂停。暂停的活动可能是具有活动更新的视频播放,即使用户正在与另一个应用进行交互,也应该对其进行更新。请注意,此实现已从可折叠手机的Android P更改为可折叠手机,在该状态下,多个活动/窗口可能处于恢复状态(无论如何,实时数据更新并不重要)。 https://android-developers.googleblog.com/2018/11/get-your-app-ready-for-foldable-phones.html

答案 3 :(得分:-1)

LiveData仅更新处于活动生命周期状态的应用程序组件观察者。

如果任何人想要执行任何与生命周期相关的工作,则必须重写onActive()和onInActive()方法。 例如:

public class StockLiveData extends LiveData<BigDecimal> {
...... 
@Override
    protected void onActive() {

    }

    @Override
    protected void onInactive() {

    }
}

重要专线:

  

添加了生命周期的观察者将在以下情况下自动删除:   相应的生命周期将变为DESTROYED状态。