庖丁解牛 Activity 启动流程
前言
这是 android 9.0 aosp 系列 的第五篇了,先来回顾一下前面几篇的大致内容。
主要介绍了 android 世界的第一个 java 进程 zygote
的启动过程。
- 注册服务端 socket,用于响应客户端请求
- 各种预加载操作,类,资源,共享库等
- 强制 gc 一次
- fork systemserver 进程
- 循环等待客户端发来的 socket 请求(请求 socket 连接和请求 fork 应用进程)
主要介绍了 zygote 进程 fork 的第一个进程 systemserver
,它承载了各类系统服务的创建和启动。
语言、时区、地区等设置
虚拟机内存设置
指纹信息,binder 调用设置
looper.preparemainlooper()
,创建主线程 looper初始化 native 服务,加载
libandroid_servers.so
createsystemcontext()
,初始化系统上下文创建系统服务管理者
systemservicemanager
startbootstrapservices
,启动系统引导服务startcoreservices
,启动系统核心服务startotherservices
,启动其他服务looper.loop()
,开启消息循环
在 startotherservices
的最后会调用 ams 的 onsystemready()
方法启动桌面 activity。
主要介绍了 ams 向 zygote 请求创建应用进程的过程,即向 zygote 进程进行 socket 通信,与第一篇呼应。
调用
process.start()
创建应用进程zygoteprocess
负责和zygote
进程建立 socket 连接,并将创建进程需要的参数发送给 zygote 的 socket 服务端zygote
服务端接收到参数之后调用zygoteconnection.processonecommand()
处理参数,并 fork 进程最后通过
findstaticmain()
找到activitythread
类的 main() 方法并执行,子进程就启动了
主要介绍了 activitymanagerservice (ams)
的启动流程,它与四大组件的启动,切换,调度以及应用进程的管理息息相关。
ams 初始化,通过
activitymanagerservice.lifecycle
的构造函数中初始化setsystemprocess()
,注册各种服务,创建 processrecord,更新 oom_adj 值安装系统 provider
systemready()
,最终会启动桌面 home activity
今天要介绍的就是 activity 的启动流程了。activity 的启动是个大工程,细节十分之多。这篇文章会简单梳理整个启动流程,不会过度深入源码细节。对其中的关键问题,如 launchmode 的处理,生命周期的处理,后续会通过单独的文章深入剖析。
启动流程分析
先来一张流程图,对照着看更方便理解。
接着之前的分析,activitymanagerservice 的 systemready()
方法中最后会去启动桌面 hme activity,调用的方法是 starthomeactivitylocked
。
> activitymanagerservice.java boolean starthomeactivitylocked(int userid, string reason) { ...... intent intent = gethomeintent(); activityinfo ainfo = resolveactivityinfo(intent, stock_pm_flags, userid); if (ainfo != null) { ...... if (app == null || app.instr == null) { intent.setflags(intent.getflags() | flag_activity_new_task); final int resolveduserid = userhandle.getuserid(ainfo.applicationinfo.uid); final string myreason = reason + ":" + userid + ":" + resolveduserid; // 启动桌面 activity mactivitystartcontroller.starthomeactivity(intent, ainfo, myreason); } } else { slog.wtf(tag, "no home screen found for " + intent, new throwable()); } return true; }
调用 activitystartcontroller
的 starthomeactivity()
方法:
> activitystartcontroller.java void starthomeactivity(intent intent, activityinfo ainfo, string reason) { msupervisor.movehomestacktasktotop(reason); mlasthomeactivitystartresult = obtainstarter(intent, "starthomeactivity: " + reason) .setoutactivity(tmpoutrecord) .setcallinguid(0) .setactivityinfo(ainfo) .execute(); mlasthomeactivitystartrecord = tmpoutrecord[0]; if (msupervisor.inresumetopactivity) { msupervisor.scheduleresumetopactivities(); } }
obtainstarter()
方法返回的是 activitystarter
对象,它负责 activity 的启动,一系列 setxxx()
方法传入启动所需的各种参数,最后的 execute()
是真正的启动逻辑。
在继续看源码之前,先思考一下现在处于哪个进程?ams 是在 system_server
进程中初始化的,所以上面的工作都是在 system_server
进程发生的。而我们通常在开发过程中使用的 startactivity()
方法显然是在应用进程调用的。那么,普通的 startactivity()
方法又是怎么样的调用链呢?跟进 activity.startactivity()
方法来看一下。
> activity.java @override public void startactivity(intent intent, @nullable bundle options) { if (options != null) { startactivityforresult(intent, -1, options); } else { startactivityforresult(intent, -1); } } public void startactivityforresult(@requirespermission intent intent, int requestcode, @nullable bundle options) { if (mparent == null) { options = transferspringboardactivityoptions(options); // 调用 instrumentation.execstartactivity() 方法 instrumentation.activityresult ar = minstrumentation.execstartactivity( this, mmainthread.getapplicationthread(), mtoken, this, intent, requestcode, options); if (ar != null) { // 回调 activityresult mmainthread.sendactivityresult( mtoken, membeddedid, requestcode, ar.getresultcode(), ar.getresultdata()); } if (requestcode >= 0) { mstartedactivity = true; } cancelinputsandstartexittransition(options); } else { // 最终也是调用 instrumentation.execstartactivity() 方法 if (options != null) { mparent.startactivityfromchild(this, intent, requestcode, options); } else { mparent.startactivityfromchild(this, intent, requestcode); } } }
最终都会调用 instrumentation
的 execstartactivity()
方法。instrumentation 是个非常重要的类,activity 的启动,生命周期的回调都离不开它。后面会多次遇到这个类。
> instrumentation.java public activityresult execstartactivity( context who, ibinder contextthread, ibinder token, activity target, intent intent, int requestcode, bundle options) { iapplicationthread whothread = (iapplicationthread) contextthread; ...... try { intent.migrateextrastreamtoclipdata(); intent.preparetoleaveprocess(who); // binder 调用 ams 来启动 activity int result = activitymanager.getservice() .startactivity(whothread, who.getbasepackagename(), intent, intent.resolvetypeifneeded(who.getcontentresolver()), token, target != null ? target.membeddedid : null, requestcode, 0, null, options); // 检测启动结果 checkstartactivityresult(result, intent); } catch (remoteexception e) { throw new runtimeexception("failure from system", e); } return null; }
这里通过 binder 调用 ams 的 startactivity()
方法。activitymanager.getservice()
不用多想肯定是获取 ams 代理对象的。
> activitymanager.java public static iactivitymanager getservice() { return iactivitymanagersingleton.get(); } private static final singleton<iactivitymanager> iactivitymanagersingleton = new singleton<iactivitymanager>() { @override protected iactivitymanager create() { final ibinder b = servicemanager.getservice(context.activity_service); final iactivitymanager am = iactivitymanager.stub.asinterface(b); return am; } };
接着就进入到 ams 的 startactivity() 方法。
> activitymanagerservice.java @override public final int startactivity(iapplicationthread caller, string callingpackage, intent intent, string resolvedtype, ibinder resultto, string resultwho, int requestcode, int startflags, profilerinfo profilerinfo, bundle boptions) {setmaywait return startactivityasuser(caller, callingpackage, intent, resolvedtype, resultto, resultwho, requestcode, startflags, profilerinfo, boptions, userhandle.getcallinguserid()); } public final int startactivityasuser(iapplicationthread caller, string callingpackage, intent intent, string resolvedtype, ibinder resultto, string resultwho, int requestcode, int startflags, profilerinfo profilerinfo, bundle boptions, int userid, boolean validateincominguser) { enforcenotisolatedcaller("startactivity"); userid = mactivitystartcontroller.checktargetuser(userid, validateincominguser, binder.getcallingpid(), binder.getcallinguid(), "startactivityasuser"); // todo: switch to user app stacks here. return mactivitystartcontroller.obtainstarter(intent, "startactivityasuser") // 获取 activitystarter 对象 .setcaller(caller) .setcallingpackage(callingpackage) .setresolvedtype(resolvedtype) .setresultto(resultto) .setresultwho(resultwho) .setrequestcode(requestcode) .setstartflags(startflags) .setprofilerinfo(profilerinfo) .setactivityoptions(boptions) .setmaywait(userid) .execute(); }
接下来和之前启动 home activity 比较相似了。获取 activitystarter
对象,提供参数,最后 execute()
。
obtainstarter()
通过工厂模式获取 activitystarter 对象。
activitystarter obtainstarter(intent intent, string reason) { return mfactory.obtain().setintent(intent).setreason(reason); }
mfactory 的默认实现是 activitystarter.defaultfactory
。
> activitystarter.java static class defaultfactory implements factory { /** * the maximum count of starters that should be active at one time: * 1. last ran starter (for logging and post activity processing) * 2. current running starter * 3. starter from re-entry in (2) * * 同时激活的 starter 最多只能有三个。 */ private final int max_starter_count = 3; private activitystartcontroller mcontroller; private activitymanagerservice mservice; private activitystacksupervisor msupervisor; private activitystartinterceptor minterceptor; private synchronizedpool<activitystarter> mstarterpool = new synchronizedpool<>(max_starter_count); defaultfactory(activitymanagerservice service, activitystacksupervisor supervisor, activitystartinterceptor interceptor) { mservice = service; msupervisor = supervisor; minterceptor = interceptor; } @override public void setcontroller(activitystartcontroller controller) { mcontroller = controller; } @override public activitystarter obtain() { // 从同步对象池 synchronizedpool 中获取 activitystarter starter = mstarterpool.acquire(); if (starter == null) { starter = new activitystarter(mcontroller, mservice, msupervisor, minterceptor); } return starter; } @override public void recycle(activitystarter starter) { starter.reset(true /* clearrequest*/); mstarterpool.release(starter); } }
提供了一个容量为 3 的同步对象缓存池来缓存 activitystarter 对象。setxxx()
方法均为参数配置,注意 setmaywait
方法会将 maywait
参数置为 true。我们直接看它的实际执行过程,execute()
函数。
> activitystarter.java int execute() { try { if (mrequest.maywait) { // setmaywait() 方法中将 maywait 置为 true return startactivitymaywait(mrequest.caller, mrequest.callinguid, mrequest.callingpackage, mrequest.intent, mrequest.resolvedtype, mrequest.voicesession, mrequest.voiceinteractor, mrequest.resultto, mrequest.resultwho, mrequest.requestcode, mrequest.startflags, mrequest.profilerinfo, mrequest.waitresult, mrequest.globalconfig, mrequest.activityoptions, mrequest.ignoretargetsecurity, mrequest.userid, mrequest.intask, mrequest.reason, mrequest.allowpendingremoteanimationregistrylookup, mrequest.originatingpendingintent); } else { return startactivity(mrequest.caller, mrequest.intent, mrequest.ephemeralintent, mrequest.resolvedtype, mrequest.activityinfo, mrequest.resolveinfo, mrequest.voicesession, mrequest.voiceinteractor, mrequest.resultto, mrequest.resultwho, mrequest.requestcode, mrequest.callingpid, mrequest.callinguid, mrequest.callingpackage, mrequest.realcallingpid, mrequest.realcallinguid, mrequest.startflags, mrequest.activityoptions, mrequest.ignoretargetsecurity, mrequest.componentspecified, mrequest.outactivity, mrequest.intask, mrequest.reason, mrequest.allowpendingremoteanimationregistrylookup, mrequest.originatingpendingintent); } } finally { // 回收当前 activitystarter 对象 onexecutioncomplete(); } }
接着调用 startactivitymaywait()
。
> activitystarter.java private int startactivitymaywait(iapplicationthread caller, int callinguid, string callingpackage, intent intent, string resolvedtype, ivoiceinteractionsession voicesession, ivoiceinteractor voiceinteractor, ibinder resultto, string resultwho, int requestcode, int startflags, profilerinfo profilerinfo, waitresult outresult, configuration globalconfig, safeactivityoptions options, boolean ignoretargetsecurity, int userid, taskrecord intask, string reason, boolean allowpendingremoteanimationregistrylookup, pendingintentrecord originatingpendingintent) { ..... // save a copy in case ephemeral needs it final intent ephemeralintent = new intent(intent); // don't modify the client's object! // 重新创建,不修改客户端原来的 intent intent = new intent(intent); if (componentspecified && !(intent.action_view.equals(intent.getaction()) && intent.getdata() == null) && !intent.action_install_instant_app_package.equals(intent.getaction()) && !intent.action_resolve_instant_app_package.equals(intent.getaction()) && mservice.getpackagemanagerinternallocked() .isinstantappinstallercomponent(intent.getcomponent())) { intent.setcomponent(null /*component*/); componentspecified = false; } // 获取 resolveinfo resolveinfo rinfo = msupervisor.resolveintent(intent, resolvedtype, userid, 0 /* matchflags */, computeresolvefilteruid( callinguid, realcallinguid, mrequest.filtercallinguid)); ...... // collect information about the target of the intent. // 获取目标 intent 的 activityinfo activityinfo ainfo = msupervisor.resolveactivity(intent, rinfo, startflags, profilerinfo); synchronized (mservice) { final activitystack stack = msupervisor.mfocusedstack; stack.mconfigwillchange = globalconfig != null && mservice.getglobalconfiguration().diff(globalconfig) != 0; ...... final activityrecord[] outrecord = new activityrecord[1]; // 调用 startactivity() 方法 int res = startactivity(caller, intent, ephemeralintent, resolvedtype, ainfo, rinfo, voicesession, voiceinteractor, resultto, resultwho, requestcode, callingpid, callinguid, callingpackage, realcallingpid, realcallinguid, startflags, options, ignoretargetsecurity, componentspecified, outrecord, intask, reason, allowpendingremoteanimationregistrylookup, originatingpendingintent); binder.restorecallingidentity(origid); ...... if (outresult != null) { // 设置启动结果 outresult.result = res; final activityrecord r = outrecord[0]; switch(res) { case start_success: { msupervisor.mwaitingactivitylaunched.add(outresult); do { try { // 等待启动结果 mservice.wait(); } catch (interruptedexception e) { } } while (outresult.result != start_task_to_front && !outresult.timeout && outresult.who == null); if (outresult.result == start_task_to_front) { res = start_task_to_front; } break; } ...... break; } } } return res; } }
调动 startactivity()
方法来启动 activity,它有两个重载方法被依次调用。这里会等待启动结果。
> activitystarter.java private int startactivity(iapplicationthread caller, intent intent, intent ephemeralintent, string resolvedtype, activityinfo ainfo, resolveinfo rinfo, ivoiceinteractionsession voicesession, ivoiceinteractor voiceinteractor, ibinder resultto, string resultwho, int requestcode, int callingpid, int callinguid, string callingpackage, int realcallingpid, int realcallinguid, int startflags, safeactivityoptions options, boolean ignoretargetsecurity, boolean componentspecified, activityrecord[] outactivity, taskrecord intask, boolean allowpendingremoteanimationregistrylookup, pendingintentrecord originatingpendingintent) { int err = activitymanager.start_success; processrecord callerapp = null; if (caller != null) { // caller 不为空时,通过 ams 查找 processrecord callerapp = mservice.getrecordforapplocked(caller); if (callerapp != null) { callingpid = callerapp.pid; callinguid = callerapp.info.uid; } else { err = activitymanager.start_permission_denied; } } // sourcerecord 用于描述发起本次请求的 activity // resultrecord 用户描述接收启动结果的 activity // 一般情况下,这两个 activity 应该是同一个 activityrecord sourcerecord = null; activityrecord resultrecord = null; ...... // 获取启动标志 final int launchflags = intent.getflags(); ...... if (err == activitymanager.start_success && intent.getcomponent() == null) { // 未找到可以处理该 intent 的类 err = activitymanager.start_intent_not_resolved; } if (err == activitymanager.start_success && ainfo == null) { // 没有找到 intent 中指定的 activity 类 err = activitymanager.start_class_not_found; } ...... // 权限检查 boolean abort = !msupervisor.checkstartanyactivitypermission(intent, ainfo, resultwho, requestcode, callingpid, callinguid, callingpackage, ignoretargetsecurity, intask != null, callerapp, resultrecord, resultstack); abort |= !mservice.mintentfirewall.checkstartactivity(intent, callinguid, callingpid, resolvedtype, ainfo.applicationinfo); ...... // 构建 activityrecord activityrecord r = new activityrecord(mservice, callerapp, callingpid, callinguid, callingpackage, intent, resolvedtype, ainfo, mservice.getglobalconfiguration(), resultrecord, resultwho, requestcode, componentspecified, voicesession != null, msupervisor, checkedoptions, sourcerecord); ...... // 获取当前获取焦点的 activitystack final activitystack stack = msupervisor.mfocusedstack; // 如果启动一个和当前处于 resume 状态的 activity 不同 uid 的新 activity,要检查是否允许 app 切换 if (voicesession == null && (stack.getresumedactivity() == null || stack.getresumedactivity().info.applicationinfo.uid != realcallinguid)) { if (!mservice.checkappswitchallowedlocked(callingpid, callinguid, realcallingpid, realcallinguid, "activity start")) { mcontroller.addpendingactivitylaunch(new pendingactivitylaunch(r, sourcerecord, startflags, stack, callerapp)); activityoptions.abort(checkedoptions); // 不允许切换,直接返回 return activitymanager.start_switches_canceled; } } ...... // 调用重载方法 return startactivity(r, sourcerecord, voicesession, voiceinteractor, startflags, true /* doresume */, checkedoptions, intask, outactivity); }
> activitystarter.java private int startactivity(final activityrecord r, activityrecord sourcerecord, ivoiceinteractionsession voicesession, ivoiceinteractor voiceinteractor, int startflags, boolean doresume, activityoptions options, taskrecord intask, activityrecord[] outactivity) { int result = start_canceled; try { // 延时布局 mservice.mwindowmanager.defersurfacelayout(); // 调用 startactivityunchecked() 方法 result = startactivityunchecked(r, sourcerecord, voicesession, voiceinteractor, startflags, doresume, options, intask, outactivity); } finally { final activitystack stack = mstartactivity.getstack(); if (!activitymanager.isstartresultsuccessful(result) && stack != null) { stack.finishactivitylocked(mstartactivity, result_canceled, null /* intentresultdata */, "startactivity", true /* oomadj */); } // 恢复布局 mservice.mwindowmanager.continuesurfacelayout(); } poststartactivityprocessing(r, result, mtargetstack); return result; }
接着调用 startactivityunchecked()
。
> activitystarter.java private int startactivityunchecked(final activityrecord r, activityrecord sourcerecord, ivoiceinteractionsession voicesession, ivoiceinteractor voiceinteractor, int startflags, boolean doresume, activityoptions options, taskrecord intask, activityrecord[] outactivity) { // 设置启动 activity 的初始状态,包括 flag setinitialstate(r, options, intask, doresume, startflags, sourcerecord, voicesession, voiceinteractor); // 计算 mlaunchflags ,启动标志位 computelaunchingtaskflags(); // 计算 msourcestack computesourcestack(); // 设置启动标志位 mintent.setflags(mlaunchflags); // 查找可复用的 activity activityrecord reusedactivity = getreusableintentactivity(); ...... // 不等于 null 说明新的 activity 应该插入已存在的任务栈中 if (reusedactivity != null) { if (mservice.getlocktaskcontroller().islocktaskmodeviolation(reusedactivity.gettask(), (mlaunchflags & (flag_activity_new_task | flag_activity_clear_task)) == (flag_activity_new_task | flag_activity_clear_task))) { slog.e(tag, "startactivityunchecked: attempt to violate lock task mode"); return start_return_lock_task_mode_violation; } final boolean cleartopandresetstandardlaunchmode = (mlaunchflags & (flag_activity_clear_top | flag_activity_reset_task_if_needed)) == (flag_activity_clear_top | flag_activity_reset_task_if_needed) && mlaunchmode == launch_multiple; if (mstartactivity.gettask() == null && !cleartopandresetstandardlaunchmode) { mstartactivity.settask(reusedactivity.gettask()); } if (reusedactivity.gettask().intent == null) { reusedactivity.gettask().setintent(mstartactivity); } if ((mlaunchflags & flag_activity_clear_top) != 0 || isdocumentlaunchesintoexisting(mlaunchflags) || islaunchmodeoneof(launch_single_instance, launch_single_task)) { final taskrecord task = reusedactivity.gettask(); // 清空任务栈 final activityrecord top = task.performcleartaskforreuselocked(mstartactivity, mlaunchflags); if (reusedactivity.gettask() == null) { reusedactivity.settask(task); } if (top != null) { if (top.frontoftask) { top.gettask().setintent(mstartactivity); } // 触发 onnewintent() delivernewintent(top); } } ...... // 是否创建新的 task boolean newtask = false; final taskrecord tasktoaffiliate = (mlaunchtaskbehind && msourcerecord != null) ? msourcerecord.gettask() : null; ...... // 将要启动的 activity 在 task 中置顶 mtargetstack.startactivitylocked(mstartactivity, topfocused, newtask, mkeepcurtransition, moptions); if (mdoresume) { final activityrecord toptaskactivity = mstartactivity.gettask().toprunningactivitylocked(); if (!mtargetstack.isfocusable() || (toptaskactivity != null && toptaskactivity.mtaskoverlay && mstartactivity != toptaskactivity)) { mtargetstack.ensureactivitiesvisiblelocked(null, 0, !preserve_windows); mservice.mwindowmanager.executeapptransition(); } else { if (mtargetstack.isfocusable() && !msupervisor.isfocusedstack(mtargetstack)) { mtargetstack.movetofront("startactivityunchecked"); } // 调用 activitystacksupervisor.resumefocusedstacktopactivitylocked() 方法 msupervisor.resumefocusedstacktopactivitylocked(mtargetstack, mstartactivity, moptions); } } else if (mstartactivity != null) { msupervisor.mrecenttasks.add(mstartactivity.gettask()); } msupervisor.updateuserstacklocked(mstartactivity.userid, mtargetstack); msupervisor.handlenonresizabletaskifneeded(mstartactivity.gettask(), preferredwindowingmode, preferredlaunchdisplayid, mtargetstack); return start_success; }
startactivityunchecked()
方法主要除了处理了启动标记 flag ,要启动的任务栈等。这一块源码很长,上面作了大量删减,仅保留了基本的调用链。感兴趣的同学可以自行查看源文件。接下来 调用了 activitystacksupervisor
的 resumefocusedstacktopactivitylocked()
方法。
> activitystacksupervisor.java boolean resumefocusedstacktopactivitylocked( activitystack targetstack, activityrecord target, activityoptions targetoptions) { if (!readytoresume()) { return false; } // 目标 stack 就是 mfocusedstack if (targetstack != null && isfocusedstack(targetstack)) { return targetstack.resumetopactivityuncheckedlocked(target, targetoptions); } // 获取 mfocusedstack 栈顶的 activityrecord final activityrecord r = mfocusedstack.toprunningactivitylocked(); if (r == null || !r.isstate(resumed)) { mfocusedstack.resumetopactivityuncheckedlocked(null, null); } else if (r.isstate(resumed)) { // kick off any lingering app transitions form the movetasktofront operation. mfocusedstack.executeapptransition(targetoptions); } return false; }
获取待启动 activity 的 activitystack 之后并调用其 resumetopactivityuncheckedlocked()
方法。
> activitystack.java boolean resumetopactivityuncheckedlocked(activityrecord prev, activityoptions options) { if (mstacksupervisor.inresumetopactivity) { // 防止递归启动 return false; } boolean result = false; try { mstacksupervisor.inresumetopactivity = true; // 执行 resumetopactivityinnerlocked() 方法) result = resumetopactivityinnerlocked(prev, options); final activityrecord next = toprunningactivitylocked(true /* focusableonly */); if (next == null || !next.canturnscreenon()) { checkreadyforsleep(); } } finally { mstacksupervisor.inresumetopactivity = false; } return result; }
> activitystack.java private boolean resumetopactivityinnerlocked(activityrecord prev, activityoptions options) { if (!mservice.mbooting && !mservice.mbooted) { // ams 还未启动完成 return false; } ...... if (!hasrunningactivity) { // 当前 stack 没有 activity,就去找下一个 stack。可能会启动 home 应用 return resumetopactivityinnextfocusablestack(prev, options, "nomoreactivities"); } // next 就是目标 activity,将其从下面几个队列移除 mstacksupervisor.mstoppingactivities.remove(next); mstacksupervisor.mgoingtosleepactivities.remove(next); next.sleeping = false; mstacksupervisor.mactivitieswaitingforvisibleactivity.remove(next); ...... // mresumedactivity 指当前 activity if (mresumedactivity != null) { // 当有其他 activity 正处于 onresume(),先暂停它 pausing |= startpausinglocked(userleaving, false, next, false); } ...... activitystack laststack = mstacksupervisor.getlaststack(); if (next.app != null && next.app.thread != null) { ...... synchronized(mwindowmanager.getwindowmanagerlock()) { // this activity is now becoming visible. if (!next.visible || next.stopped || lastactivitytranslucent) { next.setvisibility(true); } ...... try { final clienttransaction transaction = clienttransaction.obtain(next.app.thread, next.apptoken); // deliver all pending results. arraylist<resultinfo> a = next.results; if (a != null) { final int n = a.size(); if (!next.finishing && n > 0) { if (debug_results) slog.v(tag_results, "delivering results to " + next + ": " + a); transaction.addcallback(activityresultitem.obtain(a)); } } if (next.newintents != null) { transaction.addcallback(newintentitem.obtain(next.newintents, false /* andpause */)); } next.sleeping = false; mservice.getappwarningslocked().onresumeactivity(next); mservice.showaskcompatmodedialoglocked(next); next.app.pendinguiclean = true; next.app.forceprocessstateupto(mservice.mtopprocessstate); next.clearoptionslocked(); transaction.setlifecyclestaterequest( resumeactivityitem.obtain(next.app.repprocstate, mservice.isnexttransitionforward())); mservice.getlifecyclemanager().scheduletransaction(transaction); } catch (exception e) { next.setstate(laststate, "resumetopactivityinnerlocked"); // lastresumedactivity being non-null implies there is a laststack present. if (lastresumedactivity != null) { lastresumedactivity.setstate(resumed, "resumetopactivityinnerlocked"); } slog.i(tag, "restarting because process died: " + next); if (!next.hasbeenlaunched) { next.hasbeenlaunched = true; } else if (show_app_starting_preview && laststack != null && laststack.istopstackondisplay()) { next.showstartingwindow(null /* prev */, false /* newtask */, false /* taskswitch */); } // 调用 startspecificactivitylocked() mstacksupervisor.startspecificactivitylocked(next, true, false); if (debug_stack) mstacksupervisor.validatetopactivitieslocked(); return true; } } // from this point on, if something goes wrong there is no way // to recover the activity. try { next.completeresumelocked(); } catch (exception e) { ...... } } else { ...... // 调用 startspecificactivitylocked() mstacksupervisor.startspecificactivitylocked(next, true, true); } if (debug_stack) mstacksupervisor.validatetopactivitieslocked(); return true; }
上面省略了 resumetopactivityinnerlocked()
方法中的绝大部分代码,原代码大概有四百多行。其中需要注意的是 startpausinglocked()
和 startspecificactivitylocked()
方法。
在启动 activity 之前,如果当前 activity 正处于 onresume 状态,那么需要先暂停它,即调用它的 onpause。这就是 startpausinglocked()
方法的职责。这里先不具体分析,后面会单独写一篇文章说明 activity 的声明周期调用。另外多说一句,先要执行当前 activity 的 onpause 然后才会启动目标 activity ,所以我们不能在 onpause 中执行耗时任务,会造成切换 activity 时卡顿。
另一个方法 startspecificactivitylocked()
就是启动指定 activity 了,我们继续跟下去。
> activitystacksupervisor.java void startspecificactivitylocked(activityrecord r, boolean andresume, boolean checkconfig) { // 通过 ams 查找进程是否已存在 processrecord app = mservice.getprocessrecordlocked(r.processname, r.info.applicationinfo.uid, true); // 应用进程已经存在并且已经绑定 if (app != null && app.thread != null) { try { if ((r.info.flags&activityinfo.flag_multiprocess) == 0 || !"android".equals(r.info.packagename)) { app.addpackage(r.info.packagename, r.info.applicationinfo.longversioncode, mservice.mprocessstats); } // 应用进程已存在时调用 realstartactivitylocked() realstartactivitylocked(r, app, andresume, checkconfig); return; } catch (remoteexception e) { slog.w(tag, "exception when starting activity " + r.intent.getcomponent().flattentoshortstring(), e); } // if a dead object exception was thrown -- fall through to // restart the application. } // 应用进程不存在则创建进程 mservice.startprocesslocked(r.processname, r.info.applicationinfo, true, 0, "activity", r.intent.getcomponent(), false, false, true); }
首先通过 ams 查找应用进程是否已经存在,如果已经存在并且 attach ,则调用 realstartactivitylocked()
直接启动目标 activity 。如果应用进程不存在,则先创建应用进程。
在 android 世界中,谁喊醒了 zygote ? 已经介绍过了应用进程的创建过程。这里再简单说一下,zygote
进程启动时开启了 localsocket 服务端,等待客户端请求。ams 作为 socket 客户端向 zygote 发出请求,zygote 收到请求之后 fork 出子进程。
今天看到一个很有意思的提问,android 中的 ipc 通信大多通过 binder 机制实现,为什么 zygote 通过 socket 跨进程通信? 说实话,我也不知道,欢迎大家留下你的看法。
接着就是 realstartactivitylocked()
,如其名字一样,真正的要启动 activity 了。
> activitystacksupervisor.java final boolean realstartactivitylocked(activityrecord r, processrecord app, boolean andresume, boolean checkconfig) throws remoteexception { if (!allpausedactivitiescomplete()) { // 直到所有的 onpause() 执行结束才会去启动新的 activity return false; } final taskrecord task = r.gettask(); final activitystack stack = task.getstack(); begindeferresume(); try { ...... // 更新进程 oom-adj 值 mservice.updatelruprocesslocked(app, true, null); mservice.updateoomadjlocked(); try { ...... // 添加 launchactivityitem final clienttransaction clienttransaction = clienttransaction.obtain(app.thread, r.apptoken); clienttransaction.addcallback(launchactivityitem.obtain(new intent(r.intent), system.identityhashcode(r), r.info, mergedconfiguration.getglobalconfiguration(), mergedconfiguration.getoverrideconfiguration(), r.compat, r.launchedfrompackage, task.voiceinteractor, app.repprocstate, r.icicle, r.persistentstate, results, newintents, mservice.isnexttransitionforward(), profilerinfo)); // 设置生命周期状态 final activitylifecycleitem lifecycleitem; if (andresume) { lifecycleitem = resumeactivityitem.obtain(mservice.isnexttransitionforward()); } else { lifecycleitem = pauseactivityitem.obtain(); } clienttransaction.setlifecyclestaterequest(lifecycleitem); // 重点 // // 调用 clientlifecyclemanager.scheduletransaction() mservice.getlifecyclemanager().scheduletransaction(clienttransaction); ...... } catch (remoteexception e) { if (r.launchfailed) { // 第二次启动失败,finish activity mservice.appdiedlocked(app); stack.requestfinishactivitylocked(r.apptoken, activity.result_canceled, null, "2nd-crash", false); return false; } // 第一次失败,重启进程并重试 r.launchfailed = true; app.activities.remove(r); throw e; } } finally { enddeferresume(); } r.launchfailed = false; ...... return true; }
上面的重点是这句代码,mservice.getlifecyclemanager().scheduletransaction(clienttransaction);
。
这里又用到了 clienttransaction
。还记得上面提到的暂停 activity 吗 ,也是通过这个类来实现的。本来准备写到生命周期的单独文章再分析,看来还是逃不过。这里穿插着说一下 clienttransaction 。
首先 mservice.getlifecyclemanager()
返回的是 clientlifecyclemanager
对象,这是在 android 9.0 中新增的类。我们看一下它的 scheduletransaction()
方法。
> clientlifecyclemanager.java void scheduletransaction(clienttransaction transaction) throws remoteexception { final iapplicationthread client = transaction.getclient(); // -> applicationthread transaction.schedule(); // clienttransaction if (!(client instanceof binder)) { transaction.recycle(); } }
跟进 schedule()
方法。
> clienttransaction.java public void schedule() throws remoteexception { mclient.scheduletransaction(this); }
这里的 mclient
是 iapplicationthread 类型,它是 applicationthread
的 binder 代理对象,所以这里会跨进程调用到 applicationthread.scheduletransaction()
方法 。 applicationthread
是 activitythread
的内部类,但不论是 applicationthread 还是 activitythread 其实都没有 scheduletransaction() 方法,所以调用的是其父类 clienttransactionhandler
的方法。
> clienttransactionhandler.java public abstract class clienttransactionhandler { /** prepare and schedule transaction for execution. */ void scheduletransaction(clienttransaction transaction) { transaction.preexecute(this); // sendmessage() 方法在 activitythread类中实现 sendmessage(activitythread.h.execute_transaction, transaction); } }
在回到 activitythread 类中看一下 sendmessage()
方法。
> activitythread.java private void sendmessage(int what, object obj, int arg1, int arg2, boolean async) { message msg = message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setasynchronous(true); } mh.sendmessage(msg); }
这里向 mh
发送了 execute_transaction
消息,并携带了 transaction 。mh 是一个 叫做 h
的 handler 类。它负责主线程消息处理,定义了大概五十多种事件。查找一下它是如何处理 execute_transaction 消息的。
> activitythread.java case execute_transaction: final clienttransaction transaction = (clienttransaction) msg.obj; // 执行 transactionexecutor.execute() mtransactionexecutor.execute(transaction); if (issystem()) { transaction.recycle(); }
调用了 transactionexecutor
的 execute()
方法。
> transactionexecutor.java` public void execute(clienttransaction transaction) { final ibinder token = transaction.getactivitytoken(); log("start resolving transaction for client: " + mtransactionhandler + ", token: " + token); // 执行 callback executecallbacks(transaction); // 执行生命周期状态 executelifecyclestate(transaction); mpendingactions.clear(); log("end resolving transaction"); }
先来看看 executecallbacks()
方法。
> transactionexecutor.java @visiblefortesting public void executecallbacks(clienttransaction transaction) { ...... final int size = callbacks.size(); for (int i = 0; i < size; ++i) { final clienttransactionitem item = callbacks.get(i); ...... item.execute(mtransactionhandler, token, mpendingactions); item.postexecute(mtransactionhandler, token, mpendingactions); .... }
核心代码就这些。执行传入的 callback 的 execute()
方法和 postexecute()
方法。还记得之前 realstartactivitylocked()
方法中调用 addcallback()
传入的参数吗?
clienttransaction.addcallback(launchactivityitem.obtain(new intent(r.intent), ......);
也就是说会执行 launchactivityitem
的 execute()
方法。
> launchactivityitem.java @override public void execute(clienttransactionhandler client, ibinder token, pendingtransactionactions pendingactions) { trace.tracebegin(trace_tag_activity_manager, "activitystart"); activityclientrecord r = new activityclientrecord(token, mintent, mident, minfo, moverrideconfig, mcompatinfo, mreferrer, mvoiceinteractor, mstate, mpersistentstate, mpendingresults, mpendingnewintents, misforward, mprofilerinfo, client); // 调用 activitythread.handlelaunchactivity() client.handlelaunchactivity(r, pendingactions, null /* customintent */); trace.traceend(trace_tag_activity_manager); }
兜兜转转,再次回到 activitythread ,执行其 handlelaunchactivity()
方法。
> activitythread.java @override public activity handlelaunchactivity(activityclientrecord r, pendingtransactionactions pendingactions, intent customintent) { ...... final activity a = performlaunchactivity(r, customintent); ...... return a; }
> activitythread.java private activity performlaunchactivity(activityclientrecord r, intent customintent) { activityinfo ainfo = r.activityinfo; if (r.packageinfo == null) { r.packageinfo = getpackageinfo(ainfo.applicationinfo, r.compatinfo, context.context_include_code); } // 获取 componentname componentname component = r.intent.getcomponent(); if (component == null) { component = r.intent.resolveactivity( minitialapplication.getpackagemanager()); r.intent.setcomponent(component); } if (r.activityinfo.targetactivity != null) { component = new componentname(r.activityinfo.packagename, r.activityinfo.targetactivity); } // 获取 context contextimpl appcontext = createbasecontextforactivity(r); activity activity = null; try { java.lang.classloader cl = appcontext.getclassloader(); // 反射创建 activity activity = minstrumentation.newactivity( cl, component.getclassname(), r.intent); strictmode.incrementexpectedactivitycount(activity.getclass()); r.intent.setextrasclassloader(cl); r.intent.preparetoenterprocess(); if (r.state != null) { r.state.setclassloader(cl); } } catch (exception e) { ...... } try { // 获取 application application app = r.packageinfo.makeapplication(false, minstrumentation); if (activity != null) { charsequence title = r.activityinfo.loadlabel(appcontext.getpackagemanager()); configuration config = new configuration(mcompatconfiguration); if (r.overrideconfig != null) { config.updatefrom(r.overrideconfig); } window window = null; if (r.mpendingremovewindow != null && r.mpreservewindow) { window = r.mpendingremovewindow; r.mpendingremovewindow = null; r.mpendingremovewindowmanager = null; } appcontext.setoutercontext(activity); activity.attach(appcontext, this, getinstrumentation(), r.token, r.ident, app, r.intent, r.activityinfo, title, r.parent, r.embeddedid, r.lastnonconfigurationinstances, config, r.referrer, r.voiceinteractor, window, r.configcallback); if (customintent != null) { activity.mintent = customintent; } r.lastnonconfigurationinstances = null; checkandblockfornetworkaccess(); activity.mstartedactivity = false; int theme = r.activityinfo.getthemeresource(); if (theme != 0) { // 设置主题 activity.settheme(theme); } activity.mcalled = false; // 执行 oncreate() if (r.ispersistable()) { minstrumentation.callactivityoncreate(activity, r.state, r.persistentstate); } else { minstrumentation.callactivityoncreate(activity, r.state); } if (!activity.mcalled) { throw new supernotcalledexception( "activity " + r.intent.getcomponent().toshortstring() + " did not call through to super.oncreate()"); } r.activity = activity; } r.setstate(on_create); mactivities.put(r.token, r); } catch (supernotcalledexception e) { throw e; } catch (exception e) { ...... } return activity; }
这里又出现了 instrumentation
的身影,分别调用了 newactivity()
方法和 callactivityoncreate()
方法。
newactivity()
方法反射创建 activity ,并调用其 attach()
方法。
> instrumentation.java public activity newactivity(class<?> clazz, context context, ibinder token, application application, intent intent, activityinfo info, charsequence title, activity parent, string id, object lastnonconfigurationinstance) throws instantiationexception, illegalaccessexception { activity activity = (activity)clazz.newinstance(); activitythread athread = null; // activity.attach expects a non-null application object. if (application == null) { application = new application(); } activity.attach(context, athread, this, token, 0 /* ident */, application, intent, info, title, parent, id, (activity.nonconfigurationinstances)lastnonconfigurationinstance, new configuration(), null /* referrer */, null /* voiceinteractor */, null /* window */, null /* activityconfigcallback */); return activity; }
callactivityoncreate()
方法调用 activity.performcreate()
方法,最终回调 oncreate()
方法。
> instrumentation.java public void callactivityoncreate(activity activity, bundle icicle) { preperformcreate(activity); activity.performcreate(icicle); postperformcreate(activity); }
> activity.java final void performcreate(bundle icicle) { performcreate(icicle, null); } final void performcreate(bundle icicle, persistablebundle persistentstate) { mcanenterpictureinpicture = true; restorehascurrentpermissionrequest(icicle); // 回调 oncreate() if (persistentstate != null) { oncreate(icicle, persistentstate); } else { oncreate(icicle); } writeeventlog(log_am_on_create_called, "performcreate"); mactivitytransitionstate.readstate(icicle); mvisiblefromclient = !mwindow.getwindowstyle().getboolean( com.android.internal.r.styleable.window_windownodisplay, false); mfragments.dispatchactivitycreated(); mactivitytransitionstate.setenteractivityoptions(this, getactivityoptions()); }
看到这里,有一种如释重负的感觉,终于执行到 oncreate() 方法了。其实 activity 的每个生命周期回调都是类似的调用链。
还记得是从哪个方法一路追踪到 oncreate 的吗?是 transactionexecutor
的 execute()
方法。
> transactionexecutor.java` public void execute(clienttransaction transaction) { final ibinder token = transaction.getactivitytoken(); log("start resolving transaction for client: " + mtransactionhandler + ", token: " + token); // 执行 callback executecallbacks(transaction); // 执行生命周期状态 executelifecyclestate(transaction); mpendingactions.clear(); log("end resolving transaction"); }
前面分析 executecallback()
一路追踪到 oncreate() ,接下来就要分析 executelifecyclestate()
方法了。
> transactionexecutor.java private void executelifecyclestate(clienttransaction transaction) { final activitylifecycleitem lifecycleitem = transaction.getlifecyclestaterequest(); if (lifecycleitem == null) { // no lifecycle request, return early. return; } final ibinder token = transaction.getactivitytoken(); final activityclientrecord r = mtransactionhandler.getactivityclient(token); if (r == null) { // ignore requests for non-existent client records for now. return; } // cycle to the state right before the final requested state. cycletopath(r, lifecycleitem.gettargetstate(), true /* excludelaststate */); // execute the final transition with proper parameters. lifecycleitem.execute(mtransactionhandler, token, mpendingactions); lifecycleitem.postexecute(mtransactionhandler, token, mpendingactions); }
很熟悉,又看到了 lifecycleitem.execute()
。这里的 lifecycleitem
还是在 realstartactivitylocked()
方法中赋值的。
lifecycleitem = resumeactivityitem.obtain(mservice.isnexttransitionforward());
但在分析 resumeactivityitem
之前,注意一下 execute()
方法之前的 cycletopath()
方法。具体源码就不去分析了,它的作用时根据上次最后执行到的生命周期状态,和即将执行的生命周期状态进行同步。说的不是那么容易理解,举个例子,上次已经回调了 oncreate() 方法,这次要执行的是 resumeactivityitem
,中间还有一个 onstart()
状态,那么 cycletopath()
方法就会去回调 onstart()
,也就是调用 activitythread.handlestartactivity()
。和 handlelaunchactivity()
差不多的调用链。
那么,再回到 resumeactivityitem.execute()
。
> resumeactivityitem.java @override public void execute(clienttransactionhandler client, ibinder token, pendingtransactionactions pendingactions) { trace.tracebegin(trace_tag_activity_manager, "activityresume"); client.handleresumeactivity(token, true /* finalstaterequest */, misforward, "resume_activity"); trace.traceend(trace_tag_activity_manager); }
依旧是调用 activitythread.handleresumeactivity()
。不过这里有一点比较特殊,还是得拎出来说一下。
文章首发微信公众号:
秉心说
, 专注 java 、 android 原创知识分享,leetcode 题解。更多最新原创文章,扫码关注我吧!
> activitythread.java public void handleresumeactivity(ibinder token, boolean finalstaterequest, boolean isforward, string reason) { ...... r.activity.mvisiblefromserver = true; mnumvisibleactivities++; if (r.activity.mvisiblefromclient) { // 页面可见 r.activity.makevisible(); } } // 主线程空闲时会执行 idler looper.myqueue().addidlehandler(new idler()); }
makevisible()
方法让 decorview 可见。
> activity.java void makevisible() { if (!mwindowadded) { viewmanager wm = getwindowmanager(); wm.addview(mdecor, getwindow().getattributes()); mwindowadded = true; } mdecor.setvisibility(view.visible); }
最后要注意的就是 looper.myqueue().addidlehandler(new idler())
。由于篇幅原因,这里先不介绍了,后面单独写 activity 生命周期的时候再做分析。大家可以先去源码中找找答案。
总结
一路分析过来,activity终于展示给用户了。
文章其实又臭又长,很多人可能会有疑问,看这些真的有用吗?在我看来,一个程序员最重要的两样东西就是基本功和内功。良好的基本功可以让我们轻松上手一门技术,而深厚的内功就可以让我们面对难题迎刃而解。源码能带给你的,正是这些。
最近看了 jetpack 中一些组件的源码,下一篇文章应该就是jetpack 相关了。敬请期待!
文章首发微信公众号:
秉心说
, 专注 java 、 android 原创知识分享,leetcode 题解。更多最新原创文章,扫码关注我吧!
上一篇: Python文件和数据格式化(教程)