深入源码系列——为什么LiveData可以监听生命周期

本文深入探讨了LiveData如何实现对生命周期的监听。通过源码分析,揭示了LiveData并不直接检测Activity的生命周期,而是通过在Observer分发事件前检查LifecycleOwner的状态。在Activity销毁时,通过ReportFragment调度的生命周期回调移除Observer,防止内存泄漏。文章还对比了support库和androidx库中ViewModel的注册机制差异。
摘要由CSDN通过智能技术生成

前言

LiveData的一系列源码很是蛮复杂的,涉及到support库,viewmodel,lifecyclerowner,lifeccyleRigsty等等。今天咱们简单说下其中一个方面。

正文

大家都知道,在刚开始学习LiveData的时候,都会提到一个监控生命周期,并且,在生命周期消失的时候,主动移除监听者,那么,他是怎么做到的呢。下面我们就来看看这个问题。

源码分析

没办法,要想弄清楚问题,源码是少不了的,因为单纯的语言或者文字描述太乏味了,很容易让人误解或者产生歧义。为了保证能看下去,而不是填鸭子式的记住,会采取一些有趣的方式。

LiveData怎么监控生命周期

首先第一个问题,就是LivaData怎么做到监控生命周期的。咱们先不看源码,大胆猜测一下,因为AMS或者说FrameWork层只能感知到Activity,是无法感知到LiveData的存在的,所以,肯定是从Activity传递到liveData里面去的。因为sdk的源码不能动,只能改support的源码,所以,现在有两种方式。一种是在Activity里面直接引用LivaData,这样Activity在生命周期的时候就能直接告诉LiveData,还有一种方式,就是在Activity里面引入中间变量,很明显,这里安卓选择的第二种,下面我们就跟着源码看一看。
LiveData一般和ViewModel一起使用,我们就先从ViewModel看起。

ViewModel

首先,ViewModel的创建函数如下:


    /**
     * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity
     * is alive. More detailed explanation is in {@link ViewModel}.
     * <p>
     * It uses the given {@link Factory} to instantiate new ViewModels.
     *
     * @param activity an activity, in whose scope ViewModels should be retained
     * @param factory  a {@code Factory} to instantiate new ViewModels
     * @return a ViewModelProvider instance
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull FragmentActivity activity,
            @Nullable Factory factory) {
   
        Application application = checkApplication(activity);
        if (factory == null) {
   
            factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
        }
        return new ViewModelProvider(activity.getViewModelStore(), factory);
    }

这里我们默认Factory为null,那么factory就是AndroidViewModelFactory。
接下来是重点了:activity.getViewModelStore()
这也是androidx和普通的support的区别。
可以看到,activity.getViewModelStore()使用的是FragmentActivity的方法


    /**
     * Returns the {@link ViewModelStore} associated with this activity
     *
     * @return a {@code ViewModelStore}
     * @throws IllegalStateException if called before the Activity is attached to the Application
     * instance i.e., before onCreate()
     */
    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
   
        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();
            if (nc != null) {
   
                // Restore the ViewModelStore from NonConfigurationInstances
                mViewModelStore = nc.viewModelStore;
            }
            if (mViewModelStore == null) {
   
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }

getViewModelStore()这个方法来自ViewModelStoreOwner这个接口,而FragmentActivity实现了这个接口。viewModelStore就是存储数据的,这个咱们暂时不深究。
继续看get方法

    private static final String DEFAULT_KEY =
            "androidx.lifecycle.ViewModelProvider.DefaultKey";
    @NonNull
    @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);
    }

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

        if (modelClass.isInstance(viewModel)) {
   
            //noinspection unchecked
            return (T) viewModel;
        } else {
   
            //noinspection StatementWithEmptyBody
            if (viewModel != null) {
   
                // TODO: log a warning.
            }
        }

        viewModel = mFactory.create(modelClass);
        mViewModelStore.put(key, viewModel);
        //noinspection unchecked
        return (T) viewModel;
    }

可以看到,这里就是从ViewModelStore中取数据,并且放到ViewModleStore的Hashmap变量中。
好了,ViewModel的生成看完了,似乎没有发现和LiveData监听生命周期相关的点?别急,咱么接着看。
还记得liveData的用法吗?咱们从LiveData的用法来看

viewModel.getLiveData.observe(owner,new Observer{
   ...});

这是我们常规的写法,额外多问一句,这里的Observer是,匿名内部类,会持有外部类的引用,那么这里会造成内存泄漏吗?其实,这个在看了下面内容后,问题就可以很好的回答:不会,为什么?因为LivaDate监听了生命周期,在Activity或者Fragment走onDestroy的时候,会移除这个匿名内部类Observer()。
好了,回到主题,observe里面的这个owner参数是什么?
owener其实就是LifecycleOwner,一般这个owner我们直接传入FragmentActivity的实例,所以,FragmentActivity肯定继承了这个类,事实上,Fragment继承了ComponentActivity,而ComponentActivity实现了LifecycleOwner,来看下LifecycleOwner的实现

	public class ComponentActivity extends Activity
        implements LifecycleOwner, KeyEventDispatcher.Component {
   
        
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
	    @Override
	    public Lifecycle getLifecycle() {
   
	        return mLifecycleRegistry;
	    }
    }

而LifecycleRegistry又弱引用持有了activity实例
public class LifecycleRegistry extends Lifecycle {

public class LifecycleRegistry extends Lifecycle {
   
    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
   
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }
}    

可以看到,LifecycleRegistry(即Lifecycle)和LifecycleOwner(即ComponentActivity)相互持有。
而LifeCycleOwner的唯一方法getLifecycle()返回的就是mLifecycleRegistry(有点绕,可以类比mvp中v和p的关系),而Lif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值