以Activity A 启动 Activity B,Activity B所在进程未启动为例
大体经过已经几个阶段:
第一步 Activity A 调用AMS 启动接口
这是一个binder通讯,正常启动Activity的方式,一般我们都会通过以下的方式启动一个新的Activity
startActivity(new Intent(A_Activity.this,B_Activity.class));
这是Activity类的接口,最终会调用到
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
}
}
这里关键点会调用Instrumentation 的execStartActivity方法。
frameworks/base/core/java/android/app/Instrumentation.java
源码注释大体意思是Instrumentation类会在应用的任何代码执行前被实列化,用来监控系统与应用的交互。可在以应用的AndroidManifest.xml中<instrumentation>标签来注册一个Instrumentation的实现。
基本上在application和activity的所有生命周期调用中,都会先调用instrumentation的相应方法。Instrumentation另一个重要作用是提供Android组件单元测试。这里不做深究。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//核心在这一句
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;
}
ActivityManager.getService().startActivity 这一步会通过binder的方式调用到AMS的接口
第二步 收集应用信息,pause ActivityA
startActivity --> startActivityAsUser -- > mActivityStarter.startActivityMayWait
这里会调用到类 ActivityStarter
/**
* Controller for interpreting how and then launching activities.
*
* This class collects all the logic for determining how an intent and flags should be turned into
* an activity and associated task and stack.
*/
class ActivityStarter
从注释上看,我们了解了ActivityStarter的作用是收集所有的逻辑,用来决定如何启动activity, ActivityStarter又通过ActivityStackSupervisor来管理ActivityStack
略过中间环节,会调用到ActivityStack的resumeTopActivityInnerLocked
boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// ......
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
// ......
if (next.attachedToProcess()) {
try {
// ......
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
// ......
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
// ......
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
此处先通过startPausingLocked流程使mResumedActivity pause。
第三步 通过Zygote创建应用进程
下一步则通过 ActivityStackSupervisor 中的startSpecificActivityLocked方法来执行启动ActivityB流程
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
if (app != null && app.thread != null) {
try {
realStartActivityLocked(r, app, andResume, checkConfig);
return;
}
// 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);
}
这个函数,先判断ActivityB所在的进程是否启动,如果已经启动则执行realStartActivityLocked, 如果没有则走mService.startProcessLocked流程去启动一个进程. mService为ActivityManagerService
private final void startProcessLocked(ProcessRecord app,) {
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
startResult = Process.start(entryPoint,);
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
}
frameworks/base/core/java/android/os/Process.java
public static final ProcessStartResult start(final String processClass,) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
frameworks/base/core/java/android/os/Process.java
public final Process.ProcessStartResult start(final String processClass,) {
try {
return startViaZygote(processClass, );
}
}
这里 entryPoint = "android.app.ActivityThread" 为启动的java类, 该变量会作为参数给到Process。 Process.start(entryPoint,) 最终会通过socket跟Zygote通讯,Zygote 会去fork一个进程,入口就是entryPoint。
Zygote启动完进程后会返回一个pid,这个pid包含在startResult里面,接着会将pid和app 放入mPidsSelfLocked, 并发送一个延时消息,如果ActivityThread在一定的TIMEOUT(10s)还没向AMS报告,则该消息会被执行,AMS会去清除这个应用的所有信息
第四步 应用进程启动及跟AMS交互
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
}
private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
这里的attach就是向AMS注册
下面回到AMS中去执行
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
//首先根据pid取出 ProcessRecord
app = mPidsSelfLocked.get(pid);
//thread为应用端的binder对象,会去通知应用端做一些Application初始化
thread.bindApplication(processName,...)
...
//处理被挂起的应用组件(activity,service,broadcast),之前应用进程还没被创建
mStackSupervisor.attachApplicationLocked(app)
...
mServices.attachApplicationLocked()
sendPendingBroadcastsLocked(app)
}
boolean attachApplicationLocked(ProcessRecord app) {
final ActivityRecord top = stack.topRunningActivityLocked();
realStartActivityLocked(activity, app,
}
stack为mFocusStack, 这一部为取出栈顶的Activity,即我们要启动的activity,虽然之前activity没启动,但ams里面栈的信息在启动进程前都已经准备好了。
final boolean realStartActivityLocked() {
app.thread.scheduleLaunchActivity
}
app为ProcessRecord对象,thread为应用注册到AMS的binder对象. 这里调用了应用的scheduleLaunchActivity,从名字看表示可以加载activity了
第五步 Activity启动
下面就切回到ActivityThread中去执行
public final void scheduleLaunchActivity() {
ActivityClientRecord r = new ActivityClientRecord();
sendMessage(H.LAUNCH_ACTIVITY, r);
}
通过发送消息给主线程去处理
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
getPackageInfoNoCheck 会去loadApk加载apk的一些信息,后面启动activity需要调用到,下面会去执行的activity的生命周期
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}
}
private Activity performLaunchActivity {
//创建一个Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// 获取之前创建的Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//创建Context, 并将Context赋值给activity
ContextImpl appContext = createBaseContextForActivity(r);
activity.attach(appContext, this, ...)
//调用到Activity onCreate函数
mInstrumentation.callActivityOnCreate(activity, r.state);
//调用到Activity onStart函数
activity.performStart();
}
大体流程可以用下图表示
参考:
网络课程 --剖析Framework面试 冲击Android高级职位