Android架构组件-LiveData实现原理分析

本文详细分析了Android架构组件LiveData的工作原理,包括确保界面与数据同步、防止内存泄漏、处理生命周期变化等方面的优势。通过源码实现,解释了LiveData如何观察数据存储并通知观察者,以及如何感知应用组件的生命周期变化。此外,还讨论了LiveData如何在配置更改后保持数据最新状态,并介绍了其在实际开发中的基础使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

LivedData作为Jetpack的一部分,在很多地方可以看到的他的身影,比如Room直接支持LiveData,Android架构规范中也有推荐使用,因此了解整个实现原理,更有助于我们在开发中灵活的使用。

使用LiveData的优势:

1. 确保界面符合数据状态

LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面

2.不会发生内存泄漏

观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。

3.不会因 Activity 停止而导致崩溃

如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。

4.不再需要手动处理生命周期

界面组件只是观察相关数据,不会停止或恢复观察。LiveData
将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化

5.数据始终保持最新状态

如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。

6.适当的配置更改

如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。

7.共享资源

您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象

为了解如何实现以上优势,我们需要自己手写一遍源码,这样所有的疑惑解答

源码实现

一、 实现可观察的数据存储器

可观察的数据存储器是它的基本功能,我们的第一步就是实现它;可观察的数据存储器,顾名思义:第一,可以存储数据;第二:数据发生变化时可以通知观察者。

第一步,定义观察者,当数据发生变化的时候,可通过该观察者进行回调处理。

public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(T t);
}

第二步,定义数据存储类

public  class LiveData<T> {
    static final Object NOT_SET = new Object();
    //数据存储
    private volatile Object mData = NOT_SET;
    static final int START_VERSION = -1;

    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

    /**
     * 注册观察者
     * @param observer 该observer可监听所有的事件,观察者一直处于活跃状态,只要数据发生变化,就能收到事件回调
     */
    public void observeForever(Observer<? super T> observer) {
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        //同一个observer存储一次
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if(existing != null){
            return;
        }
        //新注册的观察者,默认设置为active状态,从而能及时接收当前最新数据
        wrapper.activeStateChanged(true);
    }

    //对Observer进行包装处理
    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }
        abstract boolean shouldBeActive();
    }

    private class AlwaysActiveObserver extends ObserverWrapper {
        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }
        @Override
        boolean shouldBeActive() {
            return true;
        }
    }

}

第三步,改变数据,通知观察者

    public void setValue(T value){
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
    
    //对数据进行分发处理
    private void dispatchingValue(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;
    }
    
    //通知观察者
    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);
    }    

第三步,测试

    public static void testLiveData() {
        LiveData<String> userName = new LiveData<>();
        userName.observeForever(s -> System.out.println("new Observer A rec data:"+s));
        userName.setValue("Test");
        userName.observeForever(s -> System.out.println("new Observer B rec data:"+s));
        userName.observeForever(s -> System.out.println("new Observer C rec data:"+s));
        userName.setValue("Test Last");
    }

输出结果:

new Observer A rec data:Test
new Observer B rec data:Test
new Observer C rec data:Test
new Observer A rec data:Test Last
new Observer B rec data:Test Last
new Observer C rec data:Test Last

程序运行的结果符合预期标准,使用observeForever注册监听后,我们并没有手动移除相关的监听者,有可能会造成内存泄漏,因此,我们需要合适的时候手动调用removeObserver()方法对Observe进行移除。

二、 感知应用组件的生命变化,并针对相应的事件做相关处理

    /**
     * 1,对应的observer只有在owner处于active(Lifecycle.State#STARTED或者@link Lifecycle.State#RESUMED)的时候才能接受事件
     * 2,如果owner在Lifecycle.State#DESTROYED后会,observer会被自动移除
     * 3,如果数据在owner不是活跃状态下改变,observer不会接受任何更新,当处于活跃状态后,可接受最新的数据
     * 4,同一个observer只能对应对应的owner
     *
     * @param owner
     * @param observer
     */
    public void observe(LifecycleOwner owner, Observer<? super T> observer) {
        if (owner.getLifecycle().getCurrentState() == Lifecycle.State.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);
    }
    
    //这里的使用的是LifecycleBoundObserver,
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        final LifecycleOwner mOwner;


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

        //事件变化监听
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            //Fragment或者Activity onDestory()时移除监听,避免内存泄漏
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            //生命周期事件变化将会在这里了进行处理
            activeStateChanged(shouldBeActive());
        }

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

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

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

感知应用组件生命周期主要由LifecycleBoundObserver实现,配合Lifecycle的完成,当事件变化,判断数据是否应该通知观察者,并且当数据发生变化是,会判断当前observer状态是否active,只有active的情况才会通知相应的observer进行回调。

如何实现前言中实现的优势的呢?

有了上面的源码分析实现过程,我们一起来分析一下Livedata的这些优势是如何实现的呢?

1. 确保界面符合数据状态

观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。这块主要是Lifecycle实现,当数据发生变化,有且只有Observer处于active状态才能接收回调处理。

2. 不会发生内存泄漏(observeForever方式不考虑)

observe()方法会绑定Lifecycle对象,由LifecycleBoundObserver完成,其中实现了LifecycleEventObserver,监听DESTROYED状态,当状态变成DESTROYED时候移除观察者。

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        //Fragment或者Activity onDestory()时移除监听,避免内存泄漏
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        //生命周期事件变化将会在这里了进行处理
        activeStateChanged(shouldBeActive());
    }

3. 不会因 Activity 停止而导致崩溃(observeForever方法不考虑)

观察者生命周期处于非活跃状态(如返回栈重难点Activity),不会接受任何LiveData事件。这块实现主要由:

    private void considerNotify(ObserverWrapper observer) {
        ......
        //非active状态不会进行回调处理,其中有LifecycleBoundObserver 的shouldBeActive()方法决定
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }
    
    
    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        ......
        
        //STARETED或者RESUMED才会 return ture
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        ......

    }

4. 不再需要手动处理生命周期(observeForever方法不考虑)

因为结合了Lifecycle对象,LiveData自动完成相关处理

5. 数据始终保持最新状态

当一个后台的Activity重新回到前台,如果LiveData的数据发生改变,会立即接受最新的数据。这一块主要由以下两块完成:


    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        //内容发生改变时,数据版本发生变化
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }



    private void considerNotify(ObserverWrapper observer) {
        ......
        //非active状态不会进行回调处理,其中有LifecycleBoundObserver 的shouldBeActive()方法决定
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //如果obserer的数据版本会LiveData的最新数据版本不一致,则通知相应的观察者
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }
    
    
    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        ......
        
        //STARETED或者RESUMED才会 return ture
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        ......

    }

这里的实现过程有setValue是LiveData自身控制的mVersio和Observer.mLastVersion以及Lifecycle的生命周期事件变化共同控制完成。

6,适当的配置更改

如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据;

这里的实现需要配合ViewModel完成,ViewMode中存储LiveData,当配置更改是,ViewModel不会发生变化,但重新创建的Activity或者Fragment会重走生命周期,为LiveData添加新的Observer,因此立即接收最新的可用数据。

如何使用

优势,具体的原理了解后,就算修炼好了内功,遇到任何问题可以灵活应对,但同时我们需要修炼一些招式,从而更好的实际开发中进行快速、高效的使用;

基础使用

LiveData开发中用得更多的是其子类MutableLiveData

public class PersonViewModel extends ViewModel{
    public MutableLiveData<Person> personLiveData = new MutableLiveData<>();
    
    public void loadData(){
        //you code
        Person person = fromNet();
        //update data
        personLiveData.setValue(person);
        
    }
}


public PersonFragment extends Fragment{
    
    private PersonViewModel personViewModel;
    
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.personViewModel = new PersonViewModel(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(PersonViewModel.class);
        this.personViewModel.personLiveData.observ(this,person -> {
            // you code
            
        })
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值