源码-ComponentActivity的LifecycleOwner

原文:https://weread.qq.com/web/reader/d82322e0813ab6e2eg015684

起因:使用Dialog未dismiss时Activity关闭了,导致内存泄露
解决:给Dialog添加生命周期监听

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TipDialog(context: Context) : Dialog(context), LifecycleObserver {
init {
if (context is ComponentActivity) {
(context as ComponentActivity).lifecycle.addObserver(this)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.item_tip_dialog)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private fun onDestroy() {
if (isShowing) {
dismiss()
}
}
}

androidx.core.app.ComponentActivity默认实现了LifecycleOwner接口,getLifecycle返回的实际是一个LifecycleRegistry对象,LifecycleRegistryLifecycle唯一实现类

Lifecycle抽象类定义了添加观察者addObserver()、移除观察者removeObserver()、获取当前状态getCurrentState()

androidx.core.app.ComponentActivity都做了些什么:

1
2
3
4
5
6
@SupressLint("RestrictedApi")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}

其中ReportFragment是个无页面的Fragment用来兼容处理不是继承自FragmentActivity的视图,确保ProcessLifecycleOwner可以正常工作(让那些不是直接继承自FragmentActivity的页面可以使用Lifecycle

1
2
3
4
5
6
7
8
9
public static  void injectIfNeededIn(Activity activity){
//使用Fragment兼容处理不是继承自FragmentActivity的视图,确保ProcessLifecycleOwner可以正常工作
android.app.FragmentManager manager = activity.getFragmentManger();
if(manager.findFragmentByTag(REPORT_FRAGMENT_TAG)==null){
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commint();
//希望立即执行
manager.executePendingTransactions();
}
}

ReportFragment中可以看到对应生命周期的方法中都会执行dispatch方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart(){
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onResume(){
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}

@Override
public void onPause(){
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}

@Override
public void onStop(){
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}

@Override
public void onDestroy(){
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
//赋值为空,确保不会导致内存泄露
mProcessListener = null;
}

再来看看dispatch方法的主要代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
}
}
}

dispatch方法最终都会进入handleLifecycleEvent方法中,通过handleLifecycleEvent设置状态并通知观察者,Activity便能监听到生命周期的变化了。