系列文章索引
并发系列:线程锁事
新系列:Android11系统源码解析
-
Android11源码分析:binder是如何实现跨进程的?(创作中)
-
Android11源码分析:SurfaceFlinger是如何对vsync信号进行分发的?(创作中)
经典系列:Android10系统启动流程
前言
上一篇文章简单介绍了activity的启动流程,但只提及了与进程启动相关的部分,今天我们完整的看一看,activity是怎么被创建出来,又是如何与生命周期相绑定的
在今后的文章中,我们也将从插件化的角度来介绍,如何hook系统服务来达到加载插件activity的功能
Activity
启动流程分析
启动activity有两种调用入口
-
activity.startActivity()
用于在activity对象中启动另一个activity -
contxt.startActivity()
用于在任意位置获取Context对象来启动activity
他们的区别在于,activity中的函数会调用startActvityForResult()
,可以通过传递bundle值来传递对象(),并能在当前activity中通过onActivityResult
拿到回调结果;而ContextImp
中是直接调用函数启动activity
这两种方式最终都调用到了Instrumentation
的execStartActivity()
函数, 通过获取ActiviyTastManagerService
(后面简称ATMS)的binderProxy对象,通过binder调用执行到ATMS
的startActivity
函数
public ActivityResult execStartActivity(...) {
//省略无关代码
int result = ActivityTaskManager.getService().startActivity(...);
checkStartActivityResult(result, intent);
}
ATMS是在SystemServer中被启动的系统服务,被ActivityManagerService
(后面简称AMS)对象持有,用来处理activiy栈相关的业务逻辑
我们重点需要关注的是ActivityStater
对象,在ATMS中执行了starter.excute()
函数,内部最终执行到了executeRequest()
函数来启动activity
这里涉及到一个重要的类ActivityRecord
,用来存储activity相关的信息。我们发现对于各个组件,在系统层的设计中都是用xxxRecord(比如ProcessRecocord
,ServiceRecord
等)来存储相关的信息,以及根据其是否为null
判断其是否启动或存活
在executeRequest()
中,创建了一个ActivityRecord
对象,这里的调用流程比较复杂,我们需要关注几个重要的类,ActivityStack
,ActivityStackSupervisor
,经过一系列的流程后,最终调用了ActivityStackSupervisor
的函数startSpecificActivity()
如果进程(WindowProcessController wpc
)不为空,则直接调用realStartActivityLocked()
这里重点关注scheduleTransaction()
函数,可以看到这里持有IApplicationThread
的binderProxy对象,通过binder调用与ActivityThread进行通信,到应用层去进一步创建Activity(后面详细分析应用层activity的创建)
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(@NonNull IApplicationThread client...){
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
如果进程为空则直接创建进程
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
//...
final boolean isTop = andResume && r.isTopRunningActivity();
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity"); //启动进程
}
这里又调用了ATMS的startProcessAsync()
void startProcessAsync(...) {
...
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
我们看到这里是用来发送消息的,交给handler来处理最终的启动结果,而真正启动ActivityManagerInternal::startProcess
作为参数传递,mAmInternal是其实现类LocalService
(AMS中的内部类),最终调用到了LocalService的startProcess()
函数
com.android.server.am.ActivityManagerService.LocalService
public void startProcess(...) {
//启动进程
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */, true /* keepIfLarge */);
}
startProcessLocked()
最终调用到了ProcessList
的函数startProcessLocked()
,如果获取到ProcessRecord
不为说明进程已经启动,否则去开启进程
ActivityThread
到底是什么?
这里不得不提一下困扰我很久的一个问题:ActivityThread是怎么被启动的?
在ProcessList
中,startProcessLocked()
经过了多个重载函数的调用,最终调用到了下面的代码,与Zygote
通过socket通信,来fork出新的进程,并调用java层
这里需要关注一个参数entryPoint
(原本不在此函数中,这里是为了方便查看),ActivityThread
的全类名字符串,用来传递给zygote
boolean startProcessLocked(...) {
//...
//与Zygote通信fork出子进程
final String entryPoint = "android.app.ActivityThread"; //process的入口函数
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
return app.pid > 0;
}
zygote在循环中接收到消息后,fork出新的进程,并将其解析为ZygoteArguments
,并通过ClassLoader创建出ActivityThread
的static main
函数,封装成Runnable
对象向上返回
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
最终返回到了ZygoteInit
的main函数中
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
//省略简化无关代码
ZygoteServer zygoteServer = new ZygoteServer(isPrimaryZygote); //zygote作为服务端创建socket连接
Runnable caller = zygoteServer.runSelectLoop(abiList);
if (caller != null) {
caller.run();
}
}
至此,我们熟悉又陌生的ActvityThread
终于被创建并执行了。
但此时Process还不算真正的创建完成,因为还没有完成与AMS
的双向绑定。在main函数中,创建了ActivityThread
的实例对象,并调用了attach()
函数,在这个函数中,通过获取AMS的BinderProxy对象IActivityManager
,用来调用AMS
的attachApplication(applicationThread)
,完成bpBinder实体对象的函数
而AMS
通过在attachApplication()
中获取并持有ActivityThread中ApplicationThread
这个binder对象,来与ActivityThread进行双向通信
小结
ActivityThread的创建是通过hardcode
的方式将全类名传递给Zygote,并通过ClassLoader获取到该类的main函数,执行到应用层,并通过binder机制调用attach()
完成了与AMS
的双向调用
Activity
是如何被创建出来的?
现在回到进程已经被创建出来的时候,上面我们已经知道,如果进程(WindowProcessController wpc
)不为空,则直接调用realStartActivityLocked()
,并最终会调用ClientLifecycleManager
的scheduleTransaction()
,
通过binder调用执行到ActivityThread中的binder对象ApplicationThread
中的scheduleTransaction()
函数,最终又指向了ActivityThread的scheduleTransaction()
函数
/frameworks/base/core/java/android/app/ActivityThread.java
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
ActivityThread
是ClientTransactionHandler
的子类对象(这个类目前有且仅有一个子类实现),这里并没有对父类的scheduleTransaction()
进行复写,所以调用的是父类中的方法
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
这里的sendMessage()
为抽象类方法,由ActivityThread实现,发送了一个Tag为ActivityThread.H.EXECUTE_TRANSACTION
的消息
/frameworks/base/core/java/android/app/ActivityThread.java
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg); //通过hander发送消息
}
我们都知道,handler是Android中用来处理线程间消息通信的,这里其实也是一样,通过AMS
远程调用到ActivityThread中时,是在binder线程中运行的,而不是ActivityThread被创建的线程,因此需要通过handler把消息放到主线程进行处理
在ActivityThread中,用来接收消息的Handler对象是H
,我们接着来看handler中是如何处理消息的
public void handleMessage(Message msg) {
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
//...
break;
}
}
这里会把具体的处理交给mTransactionExecutor来处理,主要逻辑是用来执行注册的callback以及相关的生命周期(LifeCycleItem)
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
//...
executeCallbacks(transaction);
executeLifecycleState(transaction);
}
我们在回来看当时给clientTransaction添加回调和ActivityLifecycleItem
的地方,也就是realStartActivityLocked()
这个函数
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(...) throws RemoteException {
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(...); //添加回调
// Set desired final state.
final ActivityLifecycleItem lifecycleItem; //添加最终需要执行的生命周期状态
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction. //binder调用传递clientTransaction
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
小结
ActivityTread
其实是用来跟系统服务AMS通信,在应用层接收消息,并post到主线程执行创建application,开启activity,service,等业务流程
在启动Activity的过程中,用来记录activity的数据结构是ActivityRecord
,activity的生命周期和栈管理是被ATMS
系统服务实现的,并通过binder调用传递到我们实现的各个activity的生命周期回调当中
至于Activity
这个类本身的创建,是在ActivityThread
这个类的performLaunchActivity()
函数中实现的
通过ClassLoader加载对应的类,并将Context
对象attach给activity,最终通过mInstrumentation.callActivityOnCreate()
执行到activity实现类的onCreate()
函数当中
后记
关于Context的内容,今后的文章也会进一步探讨,下一篇文章,我们来分析下service是如何开启和绑定的
如果我的文章对你有所启发,请多多点赞支持,我们下期文章再见!