我是靠谱客的博主 隐形柚子,最近开发中收集的这篇文章主要介绍Jetpack LiveData源码分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

jetpack系列之Lifecycle

jetpack系列之LiveData

jetpack系列之Databinding

jetpack系列之Workmanager

一、LiveData概览

LiveData是一种可观察的数据持有者类。LiveData位于androidx.lifecycle包下,并具有生命周期感知能力,如感知Activity、Fragment 、Service等的生命周期。这种感知能力意味着使用时不需要手动处理生命周期,避免了内存泄漏等问题。

LiveData使用了观察者模式,当数据发生变化时LiveData会通知Observer完成界面更新,也就是数据驱动UI。如果观察者的生命周期处于STARED或RESUME状态,则LiveData会认为该观察者处于活跃状态。

二、从使用入手 

LiveData使用非常简单,创建LiveData保存的info数据和Observer对象,使用observe()方法将Observer对象绑定到LiveData上,Observer的onChanged方法会在数据改变时更新Textview。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val textView : TextView = findViewById(R.id.tv_textview)

    MyLiveData.info.observe(this, object: Observer<String> {
        override fun onChanged(t: String?) {
            textView.text = t // 更新TextView
        }
    })

    MyLiveData.info.observeForever(object: Observer<String> {
        override fun onChanged(t: String?) {
            textView.text = t // 更新TextView
        }
    })
    //改变数据
    MyLiveData.info.value = "主线程修改"
    thread {
        Thread.sleep(3000)
        MyLiveData.info.postValue("子线程修改")
    }
}

object MyLiveData { 
    val info: MutableLiveData<String> by lazy { MutableLiveData() }
}

可以看到LiveData有两种方法来绑定Observer对象,分别为observe()方法和observeForever()方法。两者有什么区别?

observe

observe()方法额外传入this也就是LifecycleOwner,这是因为在AppCompatActivity中父类实现了LifecycleOwner接口。这个LifecycleOwner参数相当于Lifecycle,是用来感知生命周期的关键,observe()方法内部会根据Lifecycle状态来处理,当Lifecycle处于活跃状态时才会回调到onChanged方法,相反则不会做任何事。

    @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);
        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);
    }

上面代码可以看到先做了一些稳定性判断,并保证Observer只添加一次,即一个Observer只允许和一个LifecycleOwner绑定。然后将LifecycleOwner和Observer重新包装了一层LifecycleBoundObserver,再添加到LifecycleRegistry,LifecycleRegistry相关可以看上一篇Lifecycle文章。接下来看看LifecycleBoundObserver

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

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

        @Override
        boolean shouldBeActive() {
            //Lifecycle 是STARTED 或者 RESUMED 状态时返回true
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

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

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

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

LifecycleBoundObserver间接实现了LifecycleObserver,所以生命周期发生变化时都会回调onStateChange()方法,该方法中判断宿主生命周期为DESTROYED时会移除mObserver,不需要用户手动去移除了;其他状态时会调用父类ObserverWrapper的activeStateChanged方法,如果生命周期为活跃状态,则会调用dispatchingValue方法,这个方法下文setValue再分析。

        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            ...
            //注意这里参数为this
            if (mActive) {
                dispatchingValue(this);
            }
        }

observeForever

observeForever()方法没有关联LifecycleOwner,观察者会被视为始终处于活跃状态,因此生命周期不活跃时也会收到通知,也就会有内存泄漏的风险,这个跟Handler有点像。使用observeForever()还需要手动调用RemoveObserver()来移除Observer,不像oberve方法框架已经自动处理了。

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

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

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

上面代码使用了AlwaysActiveObserver来包装Observer,它跟LifecycleBoundObserver一样都是ObserverWrapper的实现类,只不过shouldBeActive()方法直接返回true,也没有生命周期变化监听,所以只要数据变化就会执行回调。

三、数据更新

LiveData没有公开更新数据的方法,我们一般使用它的子类MutableLiveData,该类对外提供了两个setValue()和postValue()方法,屏蔽了其他实现细节。一般在主线程使用setValue(),在子线程使用postValue(),调用这两个方法都会触发观察者的onChange()。

setValue

LiveData类中setValue()可以看到,该方法只能在主线程被调用。每次设置新value都会记录版本号mVersion++,然后调用dispatchingValue()

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        //注意这里传入null
        dispatchingValue(null);
    }

mDispatchingValue表示在正在向观察者分发新值,mDispatchInvalidated表示正在分发的新值是否失效,这两个布尔值实现了新旧值判断的逻辑。因为上面传入的initiator为null所以会走到else里,这里遍历所有注册的Observer逐个发送value,当value还未分发完外部又调用了setValue传进新值时,未分发的value将会被置为无效且重新分发新值。接下来看看最后一步considerNotify()

    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());
                    if (mDispatchInvalidated) {
                        //无效值舍弃
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        //新值分发结束
        mDispatchingValue = false;
    }

可以看到基本每个方法都会判断生命周期是否在活跃状态,时时刻刻获取Lifecycle生命周期以得到最新状态。这里的mVersion在setValue()中设置了递增,对应值从默认的-1变为0,而mLastVersion用于标记 Observer内最后一个被回调的value的版本号默认值是-1,所以不满足if判断往下走调用sonChanged()方法,流程到这就结束了。正常情况下mVersion值都是大于mLastVersion,为了防止重复向某个观察者分发值,所以加了这个判断。

利用这个判断,我们可以用来处理LiveData的粘性事件。粘性事件即先发送事件,后订阅也能收到值,LiveData默认就是支持粘性事件传递的,很多时候我们不需要粘性事件。通过反射修改mLastVersion与mVersion值相等,使代码不往下走,也就是旧值不分发即可实现关闭粘性事件。

    private void considerNotify(ObserverWrapper observer) {
        //判断是否活跃状态
        if (!observer.mActive) {
            return;
        }
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //通知观察者的onChanged方法
        observer.mObserver.onChanged((T) mData);
    }

postValue

postValue()可以在子线程中调用,因此源码中加了个锁防止多线程竞争。其主要实现就是通过Handle切换到主线程,在Runnable中调用setValue()方法分发数据,剩下逻辑就跟setValue()一样。

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        //Handler切换到主线程去执行
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

四、总结

1、LiveData主要是通过Lifecycle来感知生命周期;

2、LiveData 只会将更新通知给生命周期处于STARED或RESUME状态的观察者;

3、LiveData更新通知回调是在主线程执行的,因此只能在主线程中添加Observer;

3、LiveData类和ObserverWrapper类都会持有一个value的版本号,数据只会分发给active且版本号不同的观察者;

最后

以上就是隐形柚子为你收集整理的Jetpack LiveData源码分析的全部内容,希望文章能够帮你解决Jetpack LiveData源码分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部