JetPack 之 LiveData 使用及源码分析

LiveData 是在 Lifecycle 的基础上发展起来的,我们看看例子可以知道,需要借助于 ViewModel,我们来看个例子

public class LDActivity extends AppCompatActivity implements View.OnClickListener{

    private final static String TAG = "LDActivity";

    private NameViewModel model;
    TextView nameTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ld);
        nameTextView = findViewById(R.id.tv_user_name);


        model = new ViewModelProvider(this).get(NameViewModel.class);
//        model = ViewModelProviders.of(this).get(NameViewModel.class);

        Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                nameTextView.setText(newName);
            }
        };
        model.getCurrentName().observe(this, nameObserver);


        nameTextView.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.tv_user_name:
                model.getCurrentName().setValue("death_pohuai");
                break;
        }
    }

}

xml: activity_ld

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/tv_user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:textSize="20dp"
        android:text="2356"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

public class NameViewModel extends ViewModel {

    private MutableLiveData<String> currentName;

    public MutableLiveData<String> getCurrentName() {
        if (currentName == null) {
            currentName = new MutableLiveData<>();
        }
        return currentName;
    }

}

运行后,点击文本,发现文本的值变了。它是怎么实现的呢,说白了还是观察者模式,为什么说 LiveData 能有效避免内存泄漏呢?我们就来读读代码。


ViewModelProviders 这个类中的方法被标注为过时,但我们点进去后,发现其实还是 new 了一个 ViewModelProvider 对象,和我们上面写的一样,AppCompatActivity 继承了 ComponentActivity ,ComponentActivity 则实现了 ViewModelStoreOwner 这个接口,核心就一行代码

    @Override
    public ViewModelStore getViewModelStore() {
        ...
        if (mViewModelStore == null) {
            mViewModelStore = new ViewModelStore();
        }
        return mViewModelStore;
    }

ViewModelStore 类的逻辑也很简单,里面就是有个成员变量 HashMap<String, ViewModel>,用来储存 ViewModel。 ComponentActivity 也实现了 HasDefaultViewModelProviderFactory 接口,核心也是就一行代码

    @Override
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        ...
        mDefaultFactory = new SavedStateViewModelFactory(getApplication(), this,getIntent() != null ? getIntent().getExtras() : null);
        return mDefaultFactory;
    }

SavedStateViewModelFactory 中的逻辑稍微多点,看名字就知道它是工厂模式,构造方法最终会执行

    public SavedStateViewModelFactory(@NonNull Application application,
            @NonNull SavedStateRegistryOwner owner,
            @Nullable Bundle defaultArgs) {
        mSavedStateRegistry = owner.getSavedStateRegistry();
        mLifecycle = owner.getLifecycle();
        mDefaultArgs = defaultArgs;
        mApplication = application;
        mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
    }

这条线先看到这,记住 SavedStateViewModelFactory 构造方法中有个 mFactory, 我们继续看 ViewModelProvider 的 get() 方法

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

    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        ViewModel viewModel = mViewModelStore.get(key);
        ...
        if (mFactory instanceof KeyedFactory) {
            viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
        } else {
            viewModel = (mFactory).create(modelClass);
        }
        mViewModelStore.put(key, viewModel);
        return (T) viewModel;
    }

这是简化后的代码,mViewModelStore 是 ViewModelStore 类型,用来存储变量值,第一次进来获取的 viewModel 为null;mFactory 则为 SavedStateViewModelFactory,它是继承了 KeyedFactory 类,所以看看 create(key, modelClass) 这个方法, key 是个字符串类型,modelClass 是 class 类型

    @Override
    public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
        ...
        if (constructor == null) {
            return mFactory.create(modelClass);
        }
        ...
    }

最终会执行到这,这里的 mFactory 是 ViewModelProvider 中的 内部类 AndroidViewModelFactory,又重新绕回 ViewModelProvider 类了,我们看看

    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
            try {
                return modelClass.getConstructor(Application.class).newInstance(mApplication);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (InstantiationException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            }
        }
        return super.create(modelClass);
    }

注意了,这里面是反射,选用了一个带 Application 参数的构造方法,如果抛出异常了,则会执行 super() 方法;AndroidViewModelFactory 的基类是  NewInstanceFactory,我们看看它的方法

    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        try {
            return modelClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException("Cannot create an instance of " + modelClass, e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Cannot create an instance of " + modelClass, e);
        }
    }


    
也是反射,是无参构造,获取到 viewModel 后,把它添加到 mViewModelStore 的 map 集合中。从这里我们可以看出,NameViewModel 继承 ViewModel 并且需要保证一个默认的无参构造,类型是 public ,也就是默认即可。 上文中是 LDActivity 中创建了 NameViewModel 类型的对象,如果在 LDActivity1 或 LDActivity2 中也用这个方法,那么得到的 NameViewModel 对象是同一个,因为 mViewModelStore 的 map 有缓存作用,这样我们可以实现数据共享, NameViewModel 就像是一个伪单利一样的存在。


MutableLiveData 继承于 LiveData,MutableLiveData 中的代码比较少,只是起到一个过渡的作用,主要逻辑还是在 LiveData 中,observe() 是添加监听的方法

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        ...
        owner.getLifecycle().addObserver(wrapper);
    }

    static void assertMainThread(String methodName) {
        if (!ArchTaskExecutor.getInstance().isMainThread()) {
            throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
                    + " thread");
        }
    }

先检查当前线程是否是 UI 线程,最终还是 DefaultTaskExecutor 类在做检查,它里面有线程池和 Handler,感兴趣的可以看看;LifecycleOwner 则是上一章说的东西,在这里用来检查生命周期,如果 Activity 已经走过 onDestroy() 后,此方法就到此为止,不会继续往下执行了。 LifecycleBoundObserver 实现了 LifecycleEventObserver 接口,然后 wrapper 也被添加到 Lifecycle 的生命周期监听中了,此时随着 Activity 的生命周期执行, LifecycleBoundObserver 中也会接受到回调,看看

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

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

这个方法中,也有个判断,如果 Lifecycle 的 state 状态为 DESTROYED ,则移除 mObserver 监听,这样就保证了后续即使再有数据变化,mObserver 也不会执行了,这样就避免了不必要的内存泄漏和空指针等问题。shouldBeActive() 中判断是否存活,这里是判断 Lifecycle 的状态是否大于或等于 STARTED,我们看看 activeStateChanged() 方法

    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        mActive = newActive;
        boolean wasInactive = LiveData.this.mActiveCount == 0;
        LiveData.this.mActiveCount += mActive ? 1 : -1;
        if (wasInactive && mActive) {
            onActive();
        }
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            onInactive();
        }
        if (mActive) {
            dispatchingValue(this);
        }
    }

这个方法代码比较有意思, newActive 值相同的话,只会执行一次;刚开始 mActive 为 false,如果  newActive 为 true,则 mActiveCount 初始值为0,wasInactive 为 true,此时会执行  onActive() 方法,如果下一次调用该方法, newActive 还是true,则直接 return; newActive 为 false 时,mActiveCount 值在+1和-1后,会重新恢复为0,此时会执行 onInactive() 方法。 也就是说这两个方法是成对出现的,这两个方法其实对应的就是 Activity 的 onStart() 和 onStop() 方法,我们在自定义 LiveData 时,可以重写这两个方法,做些自己逻辑的操作。 最后看看 dispatchingValue(this) 方法,这个是只有 mActive 为 true 的时候才会调用

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        ...
        considerNotify(initiator);
        ...
    }

   private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

这是简化后的代码,在 considerNotify() 方法中,此时 mVersion 为0,observer.mLastVersion 值为 -1,所以此时这个方法也就 return 了。 LiveData 的 observe() 方法分析就先到这里了,我们看看  setValue() 和 postValue() 方法,看代码后会发现,setValue() 必须在 UI 线程中调用, postValue() 则是会通过 Handler 切换线程到 UI 线程,然后调用 setValue() 方法,

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

又是  dispatchingValue(null) 方法,此时由于参数为 null, 则 dispatchingValue() 可简化为

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        ...
        for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
            considerNotify(iterator.next().getValue());
            if (mDispatchInvalidated) {
                break;
            }
        }
        ...
    }

在 observe() 方法中,mObservers 添加了 LifecycleBoundObserver,在这个方法中,遍历了它,取出了添加到 mObservers 中的 LifecycleBoundObserver 对象,然后调用了 considerNotify() 方法,可简化为

    private void considerNotify(ObserverWrapper observer) {
        ...
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

observer.mObserver 就是我们 LDActivity 中的 nameObserver,此时调用了 onChanged() 方法,此时 mData 即为 setValue("death_pohuai") 方法中的 "death_pohuai", nameObserver 的实现方法中: nameTextView.setText(newName) ,这就是我们看到的现象。

MediatorLiveData 是 MutableLiveData 的子类,它提供了 addSource(LiveData<S> source, Observer<? super S> onChanged) 方法,意思是如果 source 这个对象里面有值变化,onChanged 马上就会执行回调,它是怎么实现的呢?看看这个方法

    @MainThread
    public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
        Source<S> e = new Source<>(source, onChanged);
        Source<?> existing = mSources.putIfAbsent(source, e);
        if (existing != null && existing.mObserver != onChanged) {
            throw new IllegalArgumentException(
                    "This source was already added with the different observer");
        }
        if (existing != null) {
            return;
        }
        if (hasActiveObservers()) {
            e.plug();
        }
    }

在这里,hasActiveObservers() 方法为false,我们只看 前两行代码就行了,创建了 Source 对象,然后添加到 mSources 集合中,看看 Source 这个类,实现了 Observer 接口

    private static class Source<V> implements Observer<V> {
        final LiveData<V> mLiveData;
        final Observer<? super V> mObserver;
        int mVersion = START_VERSION;

        Source(LiveData<V> liveData, final Observer<? super V> observer) {
            mLiveData = liveData;
            mObserver = observer;
        }

        void plug() {
            mLiveData.observeForever(this);
        }

        void unplug() {
            mLiveData.removeObserver(this);
        }

        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();
                mObserver.onChanged(v);
            }
        }
    }

又是回调,并且 plug() 中 observeForever() 方法注册了回调,removeObserver() 移除了回调。 前面说了,LiveData 会随着Activity的生命周期执行 onActive() 和 onInactive() 方法,我们看看 MediatorLiveData 的代码

    @CallSuper
    @Override
    protected void onActive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().plug();
        }
    }

    @CallSuper
    @Override
    protected void onInactive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().unplug();
        }
    }

果然,从 mSources 中获取到 Source,然后调用了 plug() 和 unplug() 方法;调用 LiveData 对象的 setValue() 赋值时,就会触发 Source 的 onChanged()方法,然后回调 mObserver 的 onChanged() 方法。这样就实现了该功能,个人觉得这个功能有点鸡肋。细心的朋友会发现,plug() 方法中 LiveData 使用的是 observeForever()方法,那么它与 observe() 方法有什么区别呢?

    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }

这里要注意,在此创建的是 AlwaysActiveObserver 对象,同时主动调用了 activeStateChanged(true) 方法,参数为 true,看看 AlwaysActiveObserver 类

    private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        @Override
        boolean shouldBeActive() {
            return true;
        }
    }

AlwaysActiveObserver 仅仅是继承了 ObserverWrapper,没有实现 LifecycleEventObserver 接口,自然有不会接受 Activity 的生命周期变化的监听事件了;并且, shouldBeActive() 方法返回的值是固定的 true, 再加上 activeStateChanged(true) 方法,也就是说在调用 observeForever() 方法时,就已经执行了 activeStateChanged(true) 方法,此时会执行 onActive() 方法。 我们再看看 removeObserver() 方法

     @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        removed.detachObserver();
        removed.activeStateChanged(false);
    }

也会调用 activeStateChanged(false) 方法,值为 false, 此时会执行 onInactive() 方法。 其实说白了,整个就是个观察者模式的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值