JetPack之LiveData与ViewModel

JetPack之LiveData与ViewModel

1.简述

LiveData从字面上看是与生命周期相关的数据,是一个数据的持有者。谷歌官方说明是“LiveData 具有生命周期感知能力,如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。”

2.使用

LiveData是一个抽象类,内部没有暴露任何公共方法,它的最简单的实现者是MutableLiveData。使用时,通过setValue或postValue来发送数据内容,后者可以在子线程中调用。简单使用示例:

public class LiveDataActivity extends AppCompatActivity {
    private static final String TAG = "LiveDataActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        MutableLiveData<String> liveData = new MutableLiveData<>();
        liveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e(TAG, "new data: " + s);
            }
        });
        liveData.setValue("hello world");
    }
}

输出为:

E/LiveDataActivity: new data: hello world

上面是LiveData的最简单的使用。事实上,Jetpack并不建议这样使用LiveData,请确保将用于更新界面的 LiveData 对象存储在 ViewModel 对象中,而不是将其存储在 Activity 或 Fragment 中,原因如下:

1)避免 Activity 和 Fragment 过于庞大。现在,这些界面控制器负责显示数据,但不负责存储数据状态。

2)将 LiveData 实例与特定的 Activity 或 Fragment 实例分离开,并使对象在配置更改后继续存在。

也就是说,LiveData一般在ViewModel中创建,以减少Activity中逻辑,同时避免Activity因为横竖屏切换导致的数据丢失。
我们将上述示例代码修改一下,使用LiveData来完成。先在项目的gradle中添加依赖(因为不同的版本中,ViewModel获取方式有点不同):

def lifecycle_version = "2.2.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"

创建SimpleViewModel.java:

public class SimpleViewModel extends ViewModel {

    private final MutableLiveData<String> mLiveData;
    private static int mCurTime = 0;

    public SimpleViewModel() {
        mLiveData = new MutableLiveData<>();
        mCurTime ++;
        mLiveData.postValue("number " + mCurTime + ", viewModel hashcode: " + hashCode());//1
    }

    public LiveData<String> getDataNotify(){
        return mLiveData;
    }
}

最后Activity中代码变成如下:

public class LiveDataActivity extends AppCompatActivity {
    private static final String TAG = "LiveDataActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        SimpleViewModel simpleViewModel = new ViewModelProvider(this)
                    .get(SimpleViewModel.class);
        simpleViewModel.getDataNotify().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e(TAG, "new data: " + s);
            }
        });
    }
}

ViewModel不能使用new来创建,而应该通过ViewModelProvider来创建,原因是如果我们通过new的方式创建,和我们不使用ViewModel+Lifecycle+LiveData的方式没什么区别,而通过ViewModelProvider,内部会协助管理ViewModel的生命周期。
我们尝试横竖屏切换,按照代码逻辑,如果LiveData重建了,那么内部的mCurTime静态成员应该每次都会自增1。实际日志输出如下:

2020-06-14 18:00:46.448 4506-4506/com.hudson.newfeaturetest E/LiveDataActivity: new data: number 1, viewModel hashcode: 202833815
2020-06-14 18:00:53.435 4506-4506/com.hudson.newfeaturetest E/LiveDataActivity: new data: number 1, viewModel hashcode: 202833815

可以发现两次结果一模一样,而且即便LiveData在ViewModel构建时的注释1处已经postValue发送了数据,横竖屏切换之后,Activity中仍然能够获取到之前的内容,也就是说ViewModel似乎帮我们把数据存储起来了。这就跟ViewModel的生命周期相关了。

3 ViewModel的生命周期

ViewModel 对象存在的时间范围是从获取 ViewModel 时传递给 ViewModelProvider 的 Lifecycle开始,ViewModel 将一直留在内存中,直到限定其存在时间范围的 Lifecycle 永久消失:对于 Activity,是在 Activity 完成时;而对于 Fragment,是在 Fragment 分离时。如下图说明了 Activity 经历屏幕旋转而后结束的过程中所处的各种生命周期状态,Fragment也是类似的。


ViewModel的生命周期.png

通常在系统首次调用 Activity 对象的 onCreate() 方法时请求 ViewModel。系统可能会在 Activity 的整个生命周期内多次调用 onCreate(),如在旋转设备屏幕时、内存不足回收Activity后的重建时。ViewModel 存在的时间范围是从您首次请求 ViewModel 直到 Activity 完成并销毁。
由于这个特性,ViewModel可以用于同一个Activity内部的多个Fragment之间来进行数据共享。

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}

public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->
           // Update the UI.
        });
    }
}

这两个 Fragment 可以使用其 Activity 范围共享 ViewModel 来处理此类通信。

需要注意的是,ViewModel存储数据的特性并不是指持久性数据,而是指在它所处的LifecycleOwner的生命周期范围内的全局存储,只要我们能拿到这个LifecycleOwner,我们便可以拿到之前它创建的那个ViewModel。如果一个Activity通过返回键点击被销毁了,destroyed,那么ViewModel也将会执行onCleared方法来清理数据,这时候你重新打开该Activity,这时会新建一个ViewModel,而不是使用之前的ViewModel,因为旧Activity已经和原来的ViewModel解绑了。我们可以继续使用上面的示例,先按下back返回键回到主页,再重新进入,对比两次的日志:

2020-06-14 18:40:05.918 5386-5386/com.hudson.newfeaturetest E/LiveDataActivity: new data: number 1, viewModel hashcode: 118099635

2020-06-14 18:40:36.477 5386-5386/com.hudson.newfeaturetest E/LiveDataActivity: new data: number 2, viewModel hashcode: 20262912

可以看到内部的静态成员自增了。

4.ViewModel源码跟踪

4.1 ViewModel的创建过程

从前面代码中的ViewModelProvider开始,我们可以找到ViewModel的创建过程
ViewModelProvider.java

...
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
    this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
            ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
            : NewInstanceFactory.getInstance());
}

 public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
    mFactory = factory;
    mViewModelStore = store;
}

...

内部通过this()方式调用了自身的构造方法,并传入两个参数,一个是ViewModelStore,另一个是Factory。
ViewModelStore从字面意思上看,它应该是我们ViewModel的存储器,因为Activity本身可以有多个ViewModel,因此可以猜测内部维护了一个ViewModel列表。在我们调用的构造方法中,ViewModelStore是通过ViewModelStoreOwner来获取的,而我们传入的ViewModelStoreOwner实际上是Activity。果然,在我们的ComponentActivity中,实现了ViewModelStoreOwner接口,如下所示:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
    LifecycleOwner,
    ViewModelStoreOwner,
    SavedStateRegistryOwner,
    OnBackPressedDispatcherOwner {
...
    public ComponentActivity() {
        Lifecycle lifecycle = getLifecycle();
        //noinspection ConstantConditions
        if (lifecycle == null) {
            throw new IllegalStateException("getLifecycle() returned null in ComponentActivity's "
                    + "constructor. Please make sure you are lazily constructing your Lifecycle "
                    + "in the first call to getLifecycle() rather than relying on field "
                    + "initialization.");
        }
        // ...
        getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();//1
                    }
                }
            }
        });

        if (19 <= SDK_INT && SDK_INT <= 23) {
            getLifecycle().addObserver(new ImmLeaksCleaner(this));
        }
    }

    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {//2
        if (getApplication() == null) {
            throw new IllegalStateException("Your activity is not yet attached to the "
                    + "Application instance. You can't request ViewModel before onCreate call.");
        }
        if (mViewModelStore == null) {
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();//3
            if (nc != null) {
                // Restore the ViewModelStore from NonConfigurationInstances
                mViewModelStore = nc.viewModelStore;
            }
            if (mViewModelStore == null) {
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }
...
}

内部在注释2处的方法中判断ViewModelStore是否为空,为空则创建新对象。注释3处的NonConfigurationInstances是Activity能在横竖屏切换时保持生命周期而不销毁的,从字面上看意思是与配置无关的实例。我们看下这个getLastNonConfigurationInstance方法:

/**
 * Retrieve the non-configuration instance data that was previously
 * returned by {@link #onRetainNonConfigurationInstance()}.  This will
 * be available from the initial {@link #onCreate} and
 * {@link #onStart} calls to the new instance, allowing you to extract
 * any useful dynamic state from the previous instance.
 *
 * <p>Note that the data you retrieve here should <em>only</em> be used
 * as an optimization for handling configuration changes.  You should always
 * be able to handle getting a null pointer back, and an activity must
 * still be able to restore itself to its previous state (through the
 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
 * function returns null.
 *
 * <p><strong>Note:</strong> For most cases you should use the {@link Fragment} API
 * {@link Fragment#setRetainInstance(boolean)} instead; this is also
 * available on older platforms through the Android support libraries.
 *
 * @return the object previously returned by {@link #onRetainNonConfigurationInstance()}
 */
@Nullable
public Object getLastNonConfigurationInstance() {
    return mLastNonConfigurationInstances != null
            ? mLastNonConfigurationInstances.activity : null;
}

与之对应的还有一个onRetainNonConfigurationInstance()方法,这两个方法与onSaveInstanceState()和onRestoreInstanceState()方法类似,这两个方法可以直接使用Object来保存Activity销毁与重建的信息。从上面的getLastNonConfigurationInstance()注释中我们看到,大部分情况下,我们可以使用Fragment的setRetainInstance来设置Fragment是否跟随Activity重建而重建。

另外在注释1处通过getLifecycle().addObserver()来给Activity的生命周期添加了一个监听器,并在内部判断Lifecycle的事件为ON_DESTROY事件且不是由于配置信息变更引起时,调用了ViewModelStore的clear方法,我们跟踪到内部,如下
ViewModelStore.java

public class ViewModelStore {
    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }

    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
}

可以看到上面ViewModelStore中确实维护了一个String为key,ViewModel为value的HashMap,并在clear方法中遍历map,依次调用了ViewModel的clear()方法

ViewModel.java

...
@MainThread
final void clear() {
    mCleared = true;
    // Since clear() is final, this method is still called on mock objects
    // and in those cases, mBagOfTags is null. It'll always be empty though
    // because setTagIfAbsent and getTag are not final so we can skip
    // clearing it
    if (mBagOfTags != null) {
        synchronized (mBagOfTags) {
            for (Object value : mBagOfTags.values()) {
                // see comment for the similar call in setTagIfAbsent
                closeWithRuntimeException(value);//2
            }
        }
    }
    onCleared();//1
}
...

在注释1处调用了我们之前ViewModel生命周期中的onCleared方法。因此验证了之前生命周期中所说的,如果Activity进入的Finished态的话,ViewModel生命周期也结束了。其实clear()方法中我们发现,ViewModel生命周期的结束,仅仅是把mCleared的标识位设置成了true,同时注释2处会调用Closeable对象的close方法,然后再调用了1处的onCleared()抽象方法。因此如果我们在ViewModel中执行一些异步耗时操作,内部逻辑依然会继续执行,直到全部完成,因此在ViewModel中,我们也应该注意这类问题,只不过这部分的内存泄漏并不会影响到Activity,因为ViewModelStore已经把它从Map中移除了。

回到之前的ViewModelProvider构造方法中,第二个参数是一个Factory,它的定义如下
ViewModelProvider.java

...
 /**
 * Implementations of {@code Factory} interface are responsible to instantiate ViewModels.
 */
public interface Factory {
    /**
     * Creates a new instance of the given {@code Class}.
     * <p>
     *
     * @param modelClass a {@code Class} whose instance is requested
     * @param <T>        The type parameter for the ViewModel.
     * @return a newly created ViewModel
     */
    @NonNull
    <T extends ViewModel> T create(@NonNull Class<T> modelClass);
}

@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
    String canonicalName = modelClass.getCanonicalName();//1
    if (canonicalName == null) {
        throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
    }
    return get(DEFAULT_KEY + ":" + canonicalName, modelClass);//2
}

@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
    ViewModel viewModel = mViewModelStore.get(key);//3

    if (modelClass.isInstance(viewModel)) {
        if (mFactory instanceof OnRequeryFactory) {
            ((OnRequeryFactory) mFactory).onRequery(viewModel);
        }
        return (T) viewModel;
    } else {
        //noinspection StatementWithEmptyBody
        if (viewModel != null) {
            // TODO: log a warning.
        }
    }
    if (mFactory instanceof KeyedFactory) {
        viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);//4
    } else {
        viewModel = (mFactory).create(modelClass);//5
    }
    mViewModelStore.put(key, viewModel);//6
    return (T) viewModel;
}
...

可以看出,这是一个ViewModel的构建工厂,也就是说,我们外界可以提供一个用于构建我们自定义ViewModel的构建工厂,然后ViewModelProvider会通过它来构建我们的实例。由于我们没有传入构建工厂,因此ViewModelProvider会为我们创建默认的构建工厂(在部分版本中必须传入构建工厂)。
ViewModelProvider的构建完成了,我们接着看get方法,注释1处获取到了class的名字,并在注释2处和DEFAULT_KEY拼接起来,DEFAULT_KEY是"androidx.lifecycle.ViewModelProvider.DefaultKey",因此最终拼接起来是"androidx.lifecycle.ViewModelProvider.DefaultKey" + 名字。最终先在注释3处获取HashMap中是否已经存储了该值,有就直接获取,没有则通过注释4或5处利用之前的构建工厂创建,然后在6处缓存起来,之后返回。至此,ViewModel分析完毕。

4.2 LiveData的数据观察者注册过程

前面分析中,ViewModelStore内部维护了一个String-ViewModel的HashMap集合,并会在Activity销毁时进行一些清理工作,也知道了为什么ViewModel能够在Activity重建了之后也能存活。上面代码中ViewModel完成创建后,我们在Activity中拿到它,并通过它获取到LiveData,然后调用了observe方法。
LiveData.java

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    assertMainThread("observe");
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1
        // ignore
        return;
    }
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    owner.getLifecycle().addObserver(wrapper);//4
}

上述逻辑中,1处首先判断LifecycleOwner是否处于销毁状态,如果是,直接忽略;2处创建一个LifecycleBoundObserver包裹了LifecycleOwner和数据监听的Observer,并在3处把它通过调用putIfAbsent存储到一个Map集合中。这个地方与之前的LifecycleRegistry类似,在前面的Lifecycle分析中,LifecycleRegistry通过维护一个Map集合,保存了所有LifecycleOwner的生命周期监听者。这里类似,LiveData内部也维护了一个集合,保存对它这个数据变动的监听者列表,存储的类型是ObserverWrapper。
LifecycleBoundObserver.java

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    @NonNull
    final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);
        mOwner = owner;
    }

    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

可以看到,LifecycleBoundObserver本身实现了LifecycleEventObserver接口,而LifecycleEventObserver接口又继承自LifecycleObserver,因此它本身也是一个LifecycleOwner(或者说Activity等)生命周期的观察者。而且在上述代码4处把它加入到了LifecycleOwner的观察者集合中。
咦?本来LiveData通过observe方法添加了一个自身数据变动的观察者到列表中,而添加到列表中的这个对象实例本身又是LifecycleOwner(或者说Activity等)的观察者。其实看上面LifecycleBoundObserver的构造方法中,外界传入的数据变动观察者交给了父类,也就是ObserverWrapper来完成。
看后面的代码逻辑,shouldBeActive()、removeObserver()是不是有点眼熟,没错在Lifecycle那篇文章中,Lifecycle的使用需要我们LifecycleOwner的监听者去主动查询LifecycleOwner的生命周期状态,然后决定是否继续进行数据的加载(那篇文章中是定位信息的获取),如果LifecycleOwner本身处于销毁状态,那么我们应该停止数据的加载操作。在这里,LiveData把外界传入的数据变动观察者移除了,也就是说LiveData将不再通知这个Observer数据变动了。这也就印证了最开始的LiveData的定义。
到这里,我们发现,原来LifecycleObserver中一些模板式的代码逻辑,现在都被LiveData帮助完成了,而我们只需要关注具体的数据获取就可以了。

4.3 LiveData的发布数据过程

LiveData通过setValue和postValue来给观察者发布数据,因此这是我们分析的入口。其实postValue本质还是调用了setValue来操作,因此只分析setValue方法。

LiveData.java

...
@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");//1
    mVersion++;
    mData = value;
    dispatchingValue(null);//2
}

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());//3
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
    //
    // we still first check observer.active to keep it as the entrance for events. So even if
    // the observer moved to an active state, if we've not received that event, we better not
    // notify for a more predictable notification order.
    if (!observer.shouldBeActive()) {//4
        observer.activeStateChanged(false);//5
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);//6
}
...

上面逻辑中,1处首先判断调用的线程是不是主线程,因为setValue方法是主线程调用的方法;2处开始分发;由于dispatchingValue传入的是null,因此调用到3处,可以看到是遍历了内部的ObserverWrapper元素,并调用considerNotify()方法;4处通过ObserverWrapper的shouldBeActive方法判断LifecycleOwner的生命状态,实际上是调用了

mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);

来获取状态,如果不是活跃状态,调用5处以便LiveData来响应不同状态下的处理,并直接返回,这里可以看出,如果LifecycleOwner没有处于活动状态的话,后续逻辑不再执行,直接返回,进一步验证了开头LiveData的生命周期感知能力;6处调用到实际的Observer的onChanged方法,即我们Activity中创建的Observer中的逻辑中。

5.总结

5.1 整体逻辑都分析完成了,总结一下大概类之间的关系

LiveData、ViewModel和Lifecycle.png

5.2 来检验一下自己

Q:LiveData是什么?
A:LiveData是一个具有生命周期感知能力的数据持有者,对于数据变动的观察者,会有选择性地针对处在活跃状态的观察者发布数据。

Q:LiveData本身可以直接在Activity使用,为什么需要ViewModel这中间的一层?
A:1.能够避免Activity或Fragment中过于庞大,使得它们只负责展示数据,而存储数据的任务交给了LiveData,而LiveData存储在ViewModel中; 2.能够把LiveData与Activity或Fragment实例分离,并保证它们配置更改不会影响数据生命周期

Q:ViewModel是如何保证配置更改的生命周期的?
A:利用了Activity中的onRetainNonConfigurationInstance来存储数据,getLastNonConfigurationInstance来获取数据。在Activity中实现了ViewModelStoreOwner接口,内部创建了一个ViewModelStore,并根据前面两个方法在配置更改时保存和获取。ViewModelStoreOwner中维护了一个ViewModel的HashMap集合,创建ViewModel时首先通过ViewModelProvider会去判断ViewModelStore中是否已经存在该ViewModel,存在则直接获取,否则通过构建工厂创建。在Activity内部添加了LifecycleOwner的生命周期观察者,并在Activity等生命周期进入Finished状态时,会遍历ViewModelStoreOwner的clear方法来清理ViewModel。

Q:LiveData如何保证对不活动的观察者不发送数据?
A:首先在对LiveData添加观察者时,会把这个观察者包裹在一个LifecycleBoundObserver中,该类实现了LifecycleEventObserver接口,而LifecycleEventObserver实现了LifecycleObserver接口。之后把包裹对象向LifecycleOwner注册,这样便监听了Activity等的生命周期,并在监听方法中判断ON_DESTROY事件,在内部移除了对生命周期的监听;此外,在LiveData发布数据后,会遍历LifecycleBoundObserver(代码中时ObserverWrapper,实际对象类型是LifecycleBoundObserver),并通过内部持有的LifecycleOwner获取当前生命周期状态,如果不属于活跃状态,将不会继续执行发送数据,当它重新处于活跃状态时,下次发布数据变动,还会通知到它。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342