app的启动方式
App启动有三种状态,每种状态都会影响App对用户可感知的时间:冷启动,热启动和温启动。
注意:在冷启动中,应用从头开始启动。在其他状态下,系统需要将后台运行中的应用带入前台。建议您始终在假定冷启动的基础上进行优化。这样做也可以提升温启动和热启动的性能。
冷启动
冷启动是指应用从头开始启动:系统进程在冷启动后才创建应用进程。发生冷启动的情况包括应用自设备启动后或系统终止应用后首次启动
特点:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化启动(SplishActivity)类(包括一系列的测量、布局、绘制),最后显示在界面上。
热启动
应用的热启动比冷启动简单得多,开销也更低。在热启动中,系统的所有工作就是将您的 Activity 带到前台。只要应用的所有 Activity 仍驻留在内存中,应用就不必重复执行对象初始化、布局膨胀和呈现。
但是,如果一些内存为响应内存整理事件(如 onTrimMemory())而被完全清除,则需要为了响应热启动事件而重新创建相应的对象。
热启动显示的屏幕上行为和冷启动场景相同:在应用完成 Activity 呈现之前,系统进程将显示空白屏幕。
温启动
温启动包含了在冷启动期间发生的部分操作;同时,它的开销要比热启动高。有许多潜在状态可视为温启动。例如:
用户在退出应用后又重新启动应用。进程可能已继续运行,但应用必须通过调用 onCreate() 从头开始重新创建 Activity。 系统将您的应用从内存中逐出,然后用户又重新启动它。进程和 Activity 需要重启,但传递到 onCreate() 的已保存的实例 state bundle 对于完成此任务有一定助益
准备知识
三大进程
Launcher进程
launcher进程是整个app启动流程的起点,负责接收用户点击屏幕事件,他的源码Launcher.java也是继承的activity,所以它其实就是一个Activity,里面实现了点击事件,长按事件,触摸等事件,可以这么理解,把Launcher想象成一个总的Activity,屏幕上各种App的Icon就是这个Activity的button,当点击Icon时,会从Launcher跳转到其他页面。
SystemServe进程
这个进程在Android进程中是非常重要的,Android中的所有服务都是在这个进程里面fork出来的,比如:WindowManagerService,PackagetManagerService, ActivityManagerService等系统服务。
app进程
就是你要启动的app所运行的进程
六个大类
ActivityManagerService(AMS)
AMS是Android 的核心服务之一,主要负责系统中的四大组件的启动、切换、调度以及应用进程的管理和调度工作,本身也是一个Binder的实现类,用来跨进程通信
Instrumentation
用于实现应用程序检测代码的基类。 在打开检测的情况下运行时,此类将在任何应用程序代码之前为您实例化,允许您监视系统与应用程序的所有交互。 Instrumentation 实现是通过 AndroidManifest.xml 的 标记向系统描述的. 一个进程只会存在一个该对象,在ActivityThread中实例化,在每个activity初始化时,会通过activity的attach方法,将该引用传递给activity,activity所有的生命周期都在该类中执行
ActivityTread
应用的入口类,通过调用main方法,开启消息循环队列。ActivityThread所在的线程被称为主线程
ApplicationThread
该类提供binder通信接口,AMS通过代理调用次app进程的本地方法,他是ActivityThread的内部类。
IActivityManager
应用程序用来跟AMS进程跨进程通信的aidl
IApplicationThread
系统进程用来跟应用进程通讯的AIDL
app 在冷启动的启动流程和源码解读
下面请看一张图片(从网络上获取的), app启动流程简述:
- 点击左面图标,Launcher通过调用startActivity来进程binder进程通信,调用SystemServe中的AMS服务的startActivity发起启动请求
2.SystemServe收到请求后,向Zygote进程发送创建进程的请求 3.Zygote进程fork出app进程,并执行ActivityThread的main方法创建ActivityThread线程。并同时初始化ApplicationThread用于和AMS通信交互 - App进程,通过Binder向sytem_server进程发起attachApplication请求,这里实际上就是APP进程通过Binder调用sytem_server进程中AMS的attachApplication方法,上面我们已经分析过,AMS的attachApplication方法的作用是将ApplicationThread对象与AMS绑定
- system_server进程在收到attachApplication的请求,进行一些准备工作后,再通过binder IPC向App进程发送handleBindApplication请求(初始化Application并调用onCreate方法)和scheduleLaunchActivity请求(创建启动Activity)。
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送BIND_APPLICATION和LAUNCH_ACTIVITY消息,这里注意的是AMS和主线程并不直接通信,而是AMS和主线程的内部类ApplicationThread通过Binder通信,ApplicationThread再和主线程通过Handler消息交互。
- 主线程在收到Message后,创建Application并调用onCreate方法,再通过反射机制创建目标Activity,并回调Activity.onCreate()等方法
- 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染后显示APP主界面。
Launcher进程通过startActivity启动app
从Launcher进程到 SystemServe进程通知AMS来startActivity的过程
Launcher.java
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {}
Launcer继承了一个Acivity,所以启动activity就从Activity.java的startActivity方法开始
Activity.java
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
...
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//Instumentation 启动activity
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());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
Instrumentation中调用execStartActivity
此处9.0和10.0的实现不同,10这边新增ATMS来处理,本文的是基于9.0的版本,后期补充10.0的源码注解
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);
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;
}
1、whoThrad及时启动actiivty的进程了,就是Launcher进程 2、可以看到启动activity的真正实现是由ActivityManagerService(简称:AMS)来接收启动activity。
通过ActivityManager.getService()获取到ActivityManagerService的代理对象, 如何获取:
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;
}
};
注释1:通过ServiceManager来获取远程服务AMS 注释2:接着简历通过AIDL实现远程链接,这样就交由远程的AMS服务通过startActivity打开activity. 到此第一阶段的通信完成
AMS通知zygote进程fork新的应用进程
该阶段AMS收到启动一个activity之后,通过进程是否需要启动一个新的进程,或者是在已有的进程中startAcivity。
AMS 通过调用startActivity方法调用内部startActivityAsUser()处理activity源码:
@Override
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) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
// 1
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")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute(); //2
}
注释1:AMS 执行startActivityAsUser()最终都交由自己实现的私有方法中来执行 注释2:在执行中最终是构造了ActivityStarter,接着调用execute().
ActivityStarter.execute()源码:
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
//此处在执行是已经
if (mRequest.mayWait) {
//1
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);
} else {
...
}
} finally {
onExecutionComplete();
}
}
注释1:前面在构造ActivityStarter已经传入了userId,所以此处判断条件成立,继续执行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) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
//1 activity开启日志
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
...
//2对一些特殊的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())) {
// intercept intents targeted directly to the ephemeral installer the
// ephemeral installer should never be started with a raw Intent; instead
// adjust the intent so it looks like a "normal" instant app launch
intent.setComponent(null /*component*/);
componentSpecified = false;
}
//3 处理intent信息,当存在多个activity时,列出reslverActivity
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0 /* matchFlags */,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
...
// 4 收集intent所指向的activity信息
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
...
final ActivityRecord[] outRecord = new ActivityRecord[1];
// 5 继续调用私有方法
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);
...
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
return res;
}
}
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) {
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
//6 获取调用者的进程记录对象
ProcessRecord callerApp = null;
...
//7 获取调用者所在的activity
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Will send result to " + resultTo + " " + sourceRecord);
if (sourceRecord != null) {
//requestcode =-1 不会进入
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
final int launchFlags = intent.getFlags();
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
// 8 activity执行结果的返回由源activity切换到新的activity
if (requestCode >= 0) {
SafeActivityOptions.abort(options);
return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
}
resultRecord = sourceRecord.resultTo;
if (resultRecord != null && !resultRecord.isInStackLocked()) {
resultRecord = null;
}
resultWho = sourceRecord.resultWho;
requestCode = sourceRecord.requestCode;
sourceRecord.resultTo = null;
if (resultRecord != null) {
resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
}
...
}
//9 错误信息的识别
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
....
}
final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
if (err != START_SUCCESS) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(
-1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
}
SafeActivityOptions.abort(options);
return err;
}
// 10 检查权限
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
inTask != null, callerApp, resultRecord, resultStack);
...
//11 没有权限终止返回
if (abort) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
RESULT_CANCELED, null);
}
// We pretend to the caller that it was really started, but
// they will just get a cancel result.
ActivityOptions.abort(checkedOptions);
return START_ABORTED;
}
//12 如果需要再次检查权限,则启动检查activity
if (mService.mPermissionReviewRequired && aInfo != null) {
...
}
...
// 13 创建activity记录
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
//14 activity栈
final ActivityStack stack = mSupervisor.mFocusedStack;
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
// 15 如果前台stack还没有resume状态的activity,则检查app是否允许切换,
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
// 16 如果不允许切换,则把要启动的activity添加到PendingActivity,并且返回
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
sourceRecord, startFlags, stack, callerApp));
ActivityOptions.abort(checkedOptions);
return ActivityManager.START_SWITCHES_CANCELED;
}
}
//17处理PendingActivity的启动,由于app switch禁用从而被hold的等待的activity,
mController.doPendingActivityLaunches(false);
//18 在此私有方法startActivity
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
在上面这三个返回值表示启动activity失败
START_INTENT_NOT_RESOLVED:从intent中无法找到相应的component START_CLASS_NOT_FOUND :从intent中无法找到相应的ActivityInfo START_NOT_VOICE_COMPATIBLE :不支持voice task
下面是ActivityStarter.java的startAcvity
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();
//1
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
// 不能启动activity 则取消关联
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;
}
注释1: 调用 startActivityUnchecked方法,
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
... 省略启动模式和flag标志的判断,有兴趣的同学可以自己去看
// 因为是启动APP,直接看此处,下面是开启新的任务栈
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 是否创建新的taskStack,xg
int result = START_SUCCESS;
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
...
} else {
//1
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityU nchecked");
}
//2
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
...
return START_SUCCESS;
}
注释1: 如果目标堆栈先前不可聚焦(该堆栈上的先前运行的顶部活动不可见),则任何先前将堆栈移至的调用都不会更新聚焦堆栈。如果现在启动新活动允许任务堆栈成为焦点,那么确保我们现在相应地更新焦点堆栈。 注释2:调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)方法
ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!readyToResume()) {
return false;
}
if (targetStack != null && isFocusedStack(targetStack)) {
//1
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
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;
}
注释1: 通过调用ActivityStack的resumeTopActivityUncheckedLocked方法
ActivityStack.java
/**
* @param prev
*/
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
//调用内部方法
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
//应用已经启动
try {
...
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.repProcState,
mService.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
+ next);
} catch (Exception e) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
}
try {
next.completeResumeLocked();
} catch (Exception e) {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
"resume-exception", true);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
} else {
//冷启动流程,需要创建Application的流程,
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);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
从上面的源码来看冷启动的流程再次调用ActivityStackSupervisor.java类中的startSpecificActivityLocked()方法进入改方法
ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//1. 此处是判断activity所在的进程信息
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
mService.mProcessStats);
}
//2.关键的一步就是此处方法。真正启动activity的方法
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.
}
//3、如果所在进程是null那么先进创建进程的操作
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
注释1:获取进程信息, 注释2:如果该activity的进程不存在则需要创建进程,执行AMS()的startProcessLocked,否则执行realStartActivityLocked()方法。此处有这个创建进程的原因activity所处的应用是冷启动,或者是应用是多进程的处理。 注释3:因为我们是冷启动的过程,所以上异步执行完毕后执行AMS是如何通知zygote创建应用的。具体看下一步
AMS通知zygote进程
通过上面的步骤知道AMS通过startProcessLocked方法创建,追踪此方法最终调用其startProcess()方法,
ActivityManagerService.java
private ProcessStartResult startProcess(String hostingType, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
//...省略代码
//1
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
//...省略代码
}
注释1: 调用Process的start方法开始进行fork,
Process.java start()开始一个新的过程。 如果启用了进程,则会创建一个新进程并在那里执行processClass的静态 main() 函数。 此函数返回后,进程将继续运行。 如果未启用进程,则会在调用方进程中创建一个新线程并在那里调用processClass 的main()。 niceName 参数(如果不是空字符串)是提供给进程的自定义名称,而不是使用 processClass。 这允许您创建易于识别的进程,即使您使用相同的基本processClass来启动它们。 当 invokeWith 不为 null 时,该进程将作为一个新的应用程序而不是 zygote fork 启动。 请注意,这仅适用于 uid 0 或 runtimeFlags 包含 DEBUG_ENABLE_DEBUGGER 时
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
//1
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
注释1: 通过ZygoteProcess调用start方法创建进程 start()方法参数说明:
processClass – 用作进程主要入口点的类。 niceName – 用于流程的更易读的名称。 uid – 进程将在其下运行的用户 ID。 gid – 进程将在其下运行的组 ID。 gids – 与进程关联的附加组 ID。 runtimeFlags – 运行时的附加标志。 targetSdkVersion – 应用程序的目标 SDK 版本。 seInfo – 新进程的 null-ok SELinux 信息。 abi – 此应用程序应使用的非空 ABI。 指令集 – null-ok 要使用的指令集。 appDataDir – 应用程序的数据目录为空。 invokeWith – null-ok 要调用的命令。 zygoteArgs – 提供给 zygote 进程的附加参数
ZygoteProcess.java
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
//1
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
//通过zygote机制启动一个新的进程
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
boolean startChildZygote,
String[] extraArgs)
throws ZygoteStartFailedEx {
//2
ArrayList<String> argsForZygote = new ArrayList<String>();
//...省略代码
synchronized(mLock) {
//3
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
注释1:调用内部类 StartViaZygote() 注释2: StartViaZygote方法会维护一个名为argsForZygote的列表,顾名思义,所有能够启动应用程序的进程的参数,都会保存在这里。然后这个列表作为一个参数,被传入到ZygoteSendArgsAndGetResult方法中,这个方法也是在StartViaZygote方法中被调用.另外要注意的是,openZygoteSocketIfNeeded方法返回结果也是作为参数传入了ZygoteSendArgsAndGetResult方法中。
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
...
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
...
}
从上面的方法看出,ZygoteSendArgsAndGetResult方法的第一个参数变成了ZygoteState,也就是说,openZygoteSocketIfNeeded方法的返回值是ZygoteState。
openZygoteSocketIfNeeded方法也处于ZygoteProcess中,就写在StartViaZygote下面,可以看到,在第6行与Zygote进程建立了连接。
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedE
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);//建立连接
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
//这里primaryZygoteState是连接主模式后返回的ZygoteState,比对其是否与需要的abi匹配
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
//如果主模式不成功,连接辅模式
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}
//匹配辅模式的abi
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
要匹配abi的原因在于,Zygote虽然可以fork自己不断创建进程,但是毕竟是有限的,而且需要资源,只有启动某个应用程序所必须的进程才有被创建的意义,这时候就在一开始的AMS中给设置一个abi,如果与后来的Zygote匹配,证明是需要被创建的。
Zygote接受AMS的请求
首先看一张时序图
在AMS发送请求完成后,Zygote会连接到一个ZygoteState,而这个ZygoteState在之前的ZygoteSendArgsAndGetResult方法中被写入了argsForZygote所保存的数据,这些数据就是请求的具体参数。
现在Zygote将会收到这些参数,并在ZygoteInit中进行相应操作。
ZygoteInit首先会执行其main方法。
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
final Runnable caller;
try {
...
//设置socket监听,
zygoteServer.registerServerSocketFromEnv(socketName);
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
...
//启动SystemServer进程的处理
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
// 等待AMS请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// command.
if (caller != null) {
caller.run();
}
}
一切都准备好了,只等AMS发来请求,下面看ZegoteServer的runSelectLoop()方法
ZegoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
//1
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
//使用while一直循环
while (true) {
...
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
ZygoteConnection connection = peers.get(i);
//一个连接一个连接的运行
//1
final Runnable command = connection.processOneCommand(this);
...
} catch (Exception e) {
...
}
}
}
}
}
可以看到这里维护了一个ZygoteConnection型的列表,每当连接不够时,就会增加,然后一个一个连接的进行执行,执行玩一个连接,就移除一个。
注释1:从命令套接字读取一个启动命令。 如果成功,一个子进程会被派生出来,并在子进程中返回一个调用子进程的 main 方法(或等效方法)的Runnable 。 null总是在父进程(zygote)中返回。 如果客户端关闭套接字,则会设置EOF条件,调用者可以通过调用ZygoteConnection.isClosedByPeer来测试该条件。
ZegoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = readArgumentList(); //读取之前写入的数据
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
...
//1
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
...
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
注释1:此处就是zegote进程fork一个进程,如果此处的pid=0,那么表示进程已经创建完成,就会调用handleChildProc()方法来处理出现的应用进程
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.invokeWith != null) {
//使用包装器命令执行一个运行时应用程序
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
...
} else {
if (!isZygote) {
//如果不是zygote进程,那么执行
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
现在回到Zegote中看zygoteInit方法以及它下面的调用的方法
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
上面的代码很简单就,调用RuntimeInit的applicationInit方法
RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
//调用内部方法
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//1
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
//2
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
//3
return new MethodAndArgsCaller(m, argv);
}
注释1: 通过传入的名字获取对应的类 注释2: 获取类中的main方法 注释3: 调用静态内部类MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
...
public void run() {
try {
// 1
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
注释1:这边调用反射,调用ActivityThread里面的Main方法。应用程序的进程就进入这main方法中。到此处zygote fork应用进程到此结束。 小结: 简单来说就是要想创建应用程序的进程,需要AMS发送请求,传入主线程名,这一请求必须符合Zygote的abi,并且将请求参数写在ZygoteState中。 然后zygote读取参数fork一个新的进程,如果返回pid =0,则应用进程创建成功
然后通过反射将主线程名转换为主线程的类,获得其main方法,通过抛出一个异常清除掉之前的堆栈帧,在main方法里面接受这个异常,并执行run方法以激活main方法,使得应用程序的进程进入到main方法中得以运行
应用进程通知AMS创建应用Application
- 应用进程通知AMS Attach application
- AMS通知应用进程创建
上面的步骤通过反射调用ActivityThread的main方法,看下源码
ActivityThread.java
public static void main(String[] args) {
...
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
//1
Looper.prepareMainLooper();
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//2
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
...
}
注释1: 实例化主线程的looper 注释2: 实例化ActivityThread 在实例化ActivityThread之后调用了attach();传入参数,注意传入的第一个参数是false
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
//此处传入的参数是fales,表示非系统级Luncer进程
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//1
final IActivityManager mgr = ActivityManager.getService();
try {
//2
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
...
}
...
}
注释1:通过ActivityManager.getService()获取IActivityManager在应用进程的代理类,此处的源码就不详细介绍了,主要介绍它的作用文章开头已经说了,是用来跟SystemService进程的用来跨进程通信的。
注释2:跨进程调用服务端的SystemSever的AMS的attachApplication方法,下面看下源码
ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
}
if (normalMode) {
try {
//执行activity的初始化
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
}
上面使用IApplicationThread来通过AIDL的跨进程通信来调用应用的ApplicationThread类中bindApplication()方法。到此SystemServe进程通知应用进程到此结束。
###应用进程根据SystemServe进程的信息创建Application。 ApplicationThread继承的是IApplicationThread.Sub.是一个代理类。SystemServe进程跟应用进程的通信处理就是该类处理的。 ####创建应用的Application ApplicationThread是ActivityThread中的一个内部类.下面看源码
ApplicationThread的源码
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions) {
...
//1
sendMessage(H.BIND_APPLICATION, data);
}
注释1:通过handler来发送消息给ActivityThread来处理,记住H.BIND_APPLICATION. 下面看ActivityThread对该消息的处理
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
private void handleBindApplication(AppBindData data) {
//...
try {
final ClassLoader cl = instrContext.getClassLoader();
//1
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
}
//...
Application app;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
try {
//2
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
}
}
//...
//3
mInstrumentation.callApplicationOnCreate(app);
}
//...
}
注释1:创建了Instrumentation。也就是startActivity的第一步。每一个应用程序都有一个Instrumentation,用于管理这个进程。
注释2:创建Application。源码就不详细说了,主要就是实例化application,并跟ActivityTread绑定 注释3:走application的生命周期,就是Application->attach->onCreate的调用顺序,有兴趣的同学可以进一步看下。
启动activity
说完bindApplication,该说说后续了,bindApplication方法之后执行的是ActivityStackSuperVisor.attachApplicationLocked方法,最终会执行到ActivityThread的handleLaunchActivity方法:
ActivityStackSuperVisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
//注意此处
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
return didSomething;
}
循环遍历ActivityStack获取activity,然后调用realStartActivityLocked()方法:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
//1
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
注释1:此处很正要,这边使用的是LaunchActivityItem. 然后调用ClientLifecycleManager.scheduleTransaction()
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
//调用ClientTransaction。schedule()
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();
}
}
//ClientTransaction.java
public void schedule() throws RemoteException {
//1
mClient.scheduleTransaction(this);
}
注释1:调用IApplicationThread的scheduleTransaction的方法,下面下面看下该Binder通信在ApplicationThrad中的实现
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//此处调用父类的ClientTransaction.java中的方法
ActivityThread.this.scheduleTransaction(transaction);
}
//ClientTransaction.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
//ActivityThread中的H类接收消息
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
//调用TransactionExcutor中的方法
mTransactionExecutor.execute(transaction);
...
break
}
}
// >>TransactionExcutor.java
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
//此处的ActivityLifecleItem是LaunchActivityItem
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
//调用ActivityLifecycleItem类中的方法
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
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);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
ClientTransactionHandler.java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//1
WindowManagerGlobal.initialize();
//2
final Activity a = performLaunchActivity(r, customIntent);
//...
return a;
}
注释1:上面的代码首先初始化了WindowManagerGlobal,这是个啥呢?没错,就是WindowManagerService了,也为后续窗口显示等作了准备。所以记住wms的初始化是在初始化Application之后。创建activity之前 注释2:此处开始表示真正开始创建Activity了,这个方法真正的实现是在ActivityThread中。
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 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);
}
// 创建ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//创建一个activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
...
//完成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;
//设置activity的主题
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//调用activity的生命周期的方法
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);
}
return activity;
}
到此,luncherActivity是真正的创建完成了。 下面在看下attach方法干了些什么
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
//创建了phoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
...
//将phoneWindow跟wms关联
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
mWindow.setColorMode(info.colorMode);
setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
enableAutofillCompatibilityIfNeeded();
}
总结
- Launcher被调用点击事件,转到Instrumentation类的startActivity方法。
- Instrumentation通过跨进程通信告诉AMS要启动应用的需求。
- AMS反馈Launcher,让Launcher进入Paused状态
- Launcher进入Paused状态,AMS转到ZygoteProcess类,并通过socket与Zygote通信,告知Zygote需要新建进程。
- Zygote fork进程,并调用ActivityThread的main方法,也就是app的入口。
- ActivityThread的main方法新建了ActivityThread实例,并新建了Looper实例,开始loop循环。
- 同时ActivityThread也告知AMS,进程创建完毕,开始创建Application,Provider,并调用Applicaiton的attach,onCreate方法。
最后就是创建上下文,通过类加载器加载Activity,调用Activity的onCreate方法。
|