在 support-v7 包中使用 LiveData
Posted 陈蒙_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在 support-v7 包中使用 LiveData相关的知识,希望对你有一定的参考价值。
文章目录
问题复现
当我们在 Activity 中使用 LiveData 时,我们一般会这么用:
public LiveDataDemoActivity extends AppCompatActivity
MutableLiveData<Integer> counter;
@Override
public void onCreate(Bundle savedInstance)
counter = new MutableLiveData<Integer>();
counter.setValue(0);
// ommited code
counter.observe(this, new Observer<Integer>()
@Override
public void onChanged(@Nullable Integer integer)
// update ui
);
问题在于,MutableLiveData#observe() 方法的第一个参数必须是 LifecycleOwner 类型的。如果上述代码里面的 AppCompatActivity 是出自 androidx 包的,则是天然支持的,我们看 androidx 里面的 AppCompatActivity:
package androidx.appcompat.app;
// ommited code
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider
// ommited code
AppCompatActivity 是继承 FragmentActivity 的:
package androidx.fragment.app;
// ommited code
public class FragmentActivity extends ComponentActivity implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodeValidator
// ommited code
继续往上追踪:
package androidx.activity;
// ommited code
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner
// ommited code
可见 androidx.appcompat.app.AppCompatActivity 确实是实现了 LifecycleOwner 接口的,可以直接使用。
解决方案
但是,由于项目工程代码历史较为悠久,很能还没迁移到 androidx 上,可能是 support-v7 里面的 AppCompatActivity。这是我们就没法直接使用 LiveData 了,必须要使其实现 LifecycleOwner 接口才能使用。
假设我们的工程基类是 BaseActivity,则我们需要做的是:
import android.support.v7.app.AppCompatActivity;
public class BaseActivity extends AppCompatActivity implements LifecycleOwner
private LifecycleRegistry mLifecycleRegistry;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mLifecycleRegistry = new LifecycleRegistry(this);
// ommited code
@NonNull
@Override
public Lifecycle getLifecycle()
return mLifecycleRegistry;
在继承 BaseActivity 的 Activity 就可以使用 LiveData 了。
这样就可以在使用 support-v7 库的 AppCompatActivity 的子类 Activity 里面使用 LiveData 了。
工作原理
为什么这样就能正常使用呢?不要在 BaseActivity 里面去重写 onCreate() 等方法去显式的调用 mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
吗?
那 MutableLiveData 是怎么知道所在页面的生命周期的呢?因为 observe() 方法是在 STARTED 和 RESUMED 的状态才会通知订阅者,只有在能感知到 Activity 声明周期的前提下才能实现上述功能。
关键的是类是 ProcessLifecycleOwnerInitializer、LifecycleDispatcher 和 ReportFragment。ProcessLifecycleOwnerInitializer 是一个 ContentProvider,在其创建的时候会初始化 LifecycleDispatcher:
public class ProcessLifecycleOwnerInitializer extends ContentProvider
@Override
public boolean onCreate()
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
LifecycleDispatcher 会在 Activity 创建的时候注入 ReportFragment:
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState)
if (activity instanceof FragmentActivity)
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(mFragmentCallback, true);
ReportFragment.injectIfNeededIn(activity);
ReportFragment 是一个不可见的 Fragment,用于分发事件。而在其内部会根据当前的生命周期变化去通知 LifecycleRegistry:
private void dispatch(Lifecycle.Event event)
Activity activity = getActivity();
if (activity instanceof LifecycleRegistryOwner)
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
if (activity instanceof LifecycleOwner)
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry)
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
进而,LifecycleRegistry 再去通知 LiveData 当前页面所处的生命周期阶段,所以 LiveData 就知道当前是否为 STARTED 和 RESUMED 状态、是否需要通知订阅者了。
待解疑问
public class ProcessLifecycleOwnerInitializer extends ContentProvider
@Override
public boolean onCreate()
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
上面代码里面的 getContext() 应该是指当前 Activity,但是 ProcessLifecycleOwnerInitializer 是在 Androidmanifest 里面注册的,应该是只初始化一次的,怎么能绑定到每个 Activity 上的呢?ProcessLifecycleOwner.init(getContext());
又是做什么的呢?
参考文档
以上是关于在 support-v7 包中使用 LiveData的主要内容,如果未能解决你的问题,请参考以下文章