5 道刁钻的 Activity 生命周期面试题,学完去吊打面试官!
===========================================================================================
虽然我们设置 Activity 的布局一般都是在 onCreate 方法里调用 setContentView 。里面是直接调用 window 的 setContentView,创建一个 DecorView 用来包住我们创建的布局。详情如下:
PhoneWindow.java
public?void?setContentView(int?layoutResID)?{
if?(mContentParent?==?null)?{
installDecor();
}?
...
//?加载布局,添加到?mContentParent
//?mContentParent?又是?DecorView?的一个子布局??
mLayoutInflater.inflate(layoutResID,?mContentParent);
}
然而这一步只是加载好了布局,生成一个 ViewTree , 具体怎么把 ViewTree 显示出来,答案就在下面:
ActivityThread.java
public?void?handleResumeActivity(...){
//?onResume?回调
ActivityClientRecord?r?=?performResumeActivity(...)
final?Activity?a?=?r.activity;
if?(r.window?==?null?&&?!a.mFinished?&&?willBeVisible)?{
r.window?=?r.activity.getWindow();
View?decor?=?r.window.getDecorView();
ViewManager?wm?=?a.getWindowManager();
wm.addView(decor,?l);//?重点
}
}
WindowManager 的 addView 方法最终将 DecorView 添加到 WMS ,实现绘制到屏幕、接收触屏事件。具体的调用链如下:
WindowManagerImpl.addView
->?WindowManagerGlobal.addView
->?ViewRootImpl.setView?????
->?ViewRootImpl.requestLayout()?//?执行?View?的绘制流程
//?通过?Binder?调用?WMS?,WMS?会添加一个?Window?相关的对象
//?应用端通过?mWindowSession?调用?WMS
//?WMS?通过?mWindow?(一个?Binder?对象)?调用应用端??
mWindowSession.addToDisplay(mWindow)?
综上,在 onResume 回调之后,会创建一个 ViewRootImpl ,有了它之后应用端就可以和 WMS 进行双向调用了。
[](
)onActivityResult 在哪两个生命周期之间回调
=========================================================================================
onActivityResult 不属于 Activity 的生命周期,一般被问到这个问题时大家都会懵逼。其实答案很简单,onActivityResult 方法的注释中就写着答案:
「You will receive this call immediately before onResume() when your activity is re-starting.」
跟一下代码(TransactionExecutor.execute 有兴趣的可以自己打断点跟一下),会发现 onActivityResult 回调先于该 Activity 的所有生命周期回调,从 B
Activity 返回 A Activity 的生命周期调用为:
B.onPause -> A.onActivityResult -> A.onRestart -> A.onStart -> A.onResume
[](
)onCreate 方法里写死循环会 ANR 吗
===================================================================================
ANR 的四种场景:
Service TimeOut: service 未在规定时间执行完成:前台服务 20s,后台 200s
BroadCastQueue TimeOut: 未在规定时间内未处理完广播:前台广播 10s 内, 后台 60s 内
ContentProvider TimeOut: publish 在 10s 内没有完成
Input Dispatching timeout: 5s 内未响应键盘输入、触摸屏幕等事件
我们可以看到,Activity 的生命周期回调的阻塞并不在触发 ANR 的场景里面,所以并不会直接触发 ANR。只不过死循环阻塞了主线程,如果系统再有上述的四种事件发生,就无法在相应的时间内处理从而触发 ANR。
评论