简述
用户在Launcher应用中点击app图标启动进入应用Activity,这个过程涉及到很多底层的知识;
例如:
- zygote孵化器fork新的进程,所有应用进程和framework进程服务都是zygote的子进程;
- 每个应有都有主线程ActivityThead去运行维护,Looper循环处理消息;
- 内部Application上下文的创建;
- Activity的启动需要AMS、PMS、WMS等服务去管理维护;
- AMS复制去管理Activity栈,内存,CPU等;
本文主要分析 :
用户点击桌面图标到Activity.onCreate()生命周期的执行;
启动过程类调用时序图
下面我们会通过这个时序图中去分析其中的核心代码;
一、核心流程分析
1.1 Launcher点击图标
packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
//点击图标
public void onClick(View v) {
// 确保在所有app启动时,或者在视图分离后,流氓点击不会通过(如果视图在触摸过程中被移除,可能会发生这种情况)。
if (v.getWindowToken() == null) {
return;
}
if (!mWorkspace.isFinishedSwitchingState()) {
return;
}
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
// 核心启动部分
final Intent intent = ((ShortcutInfo) tag).intent;
int[] pos = new int[2];
v.getLocationOnScreen(pos);
intent.setSourceBounds(new Rect(pos[0], pos[1],
pos[0] + v.getWidth(), pos[1] + v.getHeight()));
boolean success = startActivitySafely(v, intent, tag);
.......
} else if (tag instanceof FolderInfo) {
.......
} else if (v == mAllAppsButton) {
.......
}
//启动
boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
try {
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
//启动失败,Toast提示找不到Activity
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}
boolean startActivity(View v, Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
......
if (user == null || user.equals(android.os.Process.myUserHandle())) {
//Activity.java中启动
startActivity(intent);
} else {
launcherApps.startMainActivity(intent.getComponent(), user,
intent.getSourceBounds(), null);
}
......
}
从上面的Launcher源码中可以看到启动Activity最终是调用Activity.startActivity()
方法,并设置intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
在新的栈Task中启动这个Activity;关于Android体系中栈Task和Stack的概念,会单独做一个章节分析其工作原理,以及AMS是如何管控的;
这里简单说明一下Task和Stack概念:一个Task中包含多个Activity实例,可以再清单文件中配置启动模式来控制Activity实例的管控方式;而Stack中包含多个Task;
1.2 Activity启动
startActivity
方法最终调用startActivityForResult
源码地址:
frameworks/base/core/java/android/app/Activity.java
....
private Instrumentation mInstrumentation;
....
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);
..........
} else {
..........
}
}
Activity调用Instrumentation去执行启动操作;mMainThread.getApplicationThread()
返回ActivityThead
应用主线程的内部类ApplicationThread
;实现了IApplicationThread.Stub
AIDL接口方法,是App主线程ActivityThead
对外提供(这里指AMS等系统服务)的操作接口,实现AMS对App的操作;
1.3 Instrumentation执行
Instrumentation
是App与AMS沟通的桥梁,内部通过ActivityManager
调取AMS服务中的方法;
frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
......
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
..........
}
1.4 ActivityManager获取AMS服务启动
ActivityManager获取从ServiceManager获取AMS对外提供的(IActivityManager)
AIDL接口,这里通过全局App单利方式创建私有;
frameworks/base/core/java/android/app/ActivityManager.java
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;
}
};
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
1.5 AMS内部实现IActivityManager 接口
AMS属于framework层,随系统开机在SystemServer(Zygote fork出来的第二个进程)进程中启动;
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
final ActivityStarter mActivityStarter;
final UserController mUserController;
......
//构造函数中
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
mUserController = new UserController(this);
......
@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) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@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) {
enforceNotIsolatedCaller("startActivity");
//处理传入的用户 检查一下用户权限
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// 在这里切换到用户应用程序堆栈。
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
....
}
AMS中有ActivityStarter
和UserController
两个变量,UserController
用户系统多用户的管理以及权限的管理,ActivityStarter
加载Activity的控制类,决定如何将Intent和Flags转换为Activity,并且与Task、Stack关联;
1.6 ActivityStarter管理Activity启动
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
final 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, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask, String reason) {
............
//获取目标应用程序意图关联的Activity信息。
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
ActivityOptions options = ActivityOptions.fromBundle(bOptions);
ActivityStackSupervisor.ActivityContainer container =(ActivityStackSupervisor.ActivityContainer)iContainer;
............
final ActivityStack stack;
if (container == null || container.mStack.isOnHomeDisplay()) {
stack = mSupervisor.mFocusedStack;
} else {
stack = container.mStack;
}
............
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask, reason);
............
}
int startActivityLocked(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,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask, String reason) {
.........
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);
..........
return mLastStartActivityResult;
}
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,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
//山路十八弯 最后调用startActivityUnchecked()
}
}
到这里休息片刻。。。。。。。。。。。。。。。。。。
接着继续调用ActivityStarter中的startActivityUnchecked()
方法
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
// 初始化ActivityStarter全局变量
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
// // 检测Activity是否启动模式,是否需要在新的栈中启动,对与新的进程、SingleTask、SingleInstance启动模式就需要在新的栈中启动, 一般是判断是否需要在mLaunchFlags中加入FLAG_ACTIVITY_NEW_TASK
computeLaunchingTaskFlags();
//检测当前栈
computeSourceStack();
//最终确定Task启动方式
mIntent.setFlags(mLaunchFlags);
// 判断是否应将新Activity插入到现有任务栈中
// 如果不需要,则返回null,如果需要,则返回该任务栈信息
ActivityRecord reusedActivity = getReusableIntentActivity();
..............
if (reusedActivity != null) {
if (mSupervisor.isLockTaskModeViolation(reusedActivity.getTask(),
(mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
mSupervisor.showLockTaskToast();
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
}
//当我们在历史中发现一个现有的匹配活动记录时,找出应该将哪个任务和活动放在前面。如果需要,也可以清除任务。
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
.....
//设置Task栈为当前栈顶或创建先的栈
setTaskToCurrentTopOrCreateNewTask()
...
//设置Activity可见
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");
}
// 设置当前Activity所在栈为最顶可见
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
...
}
return START_SUCCESS;
}
上面代码核心工作就是为待启动的ActivityRecord找到他对应的TaskRecord和ActivityStack;
1.7 ActivityStackSupervisor设置Activity可见
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
ActivityStack mFocusedStack;
....
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//目标栈是当前栈顶 则直接回复栈顶Activity
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
// 获取要启动的Activity所在栈的栈顶的不是出于停止状态的ActivityRecord
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
mFocusedStack
是ActivityStackSupervisor存储当前App显示并拥有焦点的栈;
1.8 ActivityStack设置栈顶Activity
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
.....
boolean result = false;
result = resumeTopActivityInnerLocked(prev, options);
.....
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
........
mStackSupervisor.startSpecificActivityLocked(next, true, false);
.......
}
}
1.9 ActivityStackSupervisor启动执行Activity
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// 获取即将启动的Activiy所在的应用程序进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().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.versionCode,
mService.mProcessStats);
}
//正式启动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.
}
//如果当前应用还未创建过进程,通过AMS服务创建进程;
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
这一步的工作是获取当前目标activity所在的应用进程以及主线程是否存在,都满足条件就去启动Activity,否则就通过AMS服务startProcessLocked
启动进程;
下面分析realStartActivityLocked
方法
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
//核心代码 通知App主线程Looper去创建Activity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
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, !andResume,
mService.isNextTransitionForward(), profilerInfo);
....
}
app.thread
为IApplicationThread.aidl
,App主线程对外提供的接口;
重点:绕了一大圈,最终通过AIDL进程通信通知App进程去创建Activity
2.0 App主线程创建Activity
ActivityThread代码位置:frameworks/base/core/java/android/app/ActivityThread.java
ApplicationThread为ActivityThread内部类,并实现 IApplicationThread
AIDL接口
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
.....
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
.....
sendMessage(H.LAUNCH_ACTIVITY, r);
}
}
内部类H继承Handler
private class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//重点一:创建Activity对象
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
...
//重点二:设置Activity可见状态,并回调Activity.onResume函数
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
} else {
//创建失败,通知AMS关闭当前
try {
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
- 重点1:通过反射创建Activity对象
- 重点2:
handleResumeActivity
方法回去调用performResumeActivity
方法,最终触发到Activity.performResume()
触发Instrumentation
去执行Activity.onResume
方法,并通知试图View.setVisibility(View.VISIBLE)
,这里才是真正的可见,面试进程会问道;
2.1 反射创建Activity对象
主线程内部performLaunchActivity
函数创建Activity独享
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
//第一步:获取组件 名称,例如反射创建Activity
ComponentName component = r.intent.getComponent();
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//第二部:创建Activity上下文Context对象
ContextImpl appContext = createBaseContextForActivity(r);
//第三部:反射创建Activity实例对象
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
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) {
.........
}
//第四部:创建应用Application对象,进程内全局唯一
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
//第五部:调用Activity.attach创建PhoneWindow交付WMS管理
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);
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
}
.........
//第五步:通过Instrumentation执行Activity.onCreate()方法;
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
重点步骤:
- 第一步:获取到要启动的Activity主键信息,用于反射创建实例;
- 第二步:创建Activity的上下文对象Context;
- 第三步:通过Activity组件名,反射创建Activity对象实例;
- 第四步:如果进程第一次启动,则创建应用Application对象,进程全局唯一
- 第五步:调用Acitiivy.attach创建试图PhoneWindow窗口交付WMS管理
-
第六步:通过
Instrumentation
回调执行Activity.onCreate方法 ,下面继续分析;
2.2 Instrumentation执行Acitivity.onCreate方法
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
//per
activity.performCreate(icicle);
postPerformCreate(activity);
}
}
2.2 Acitivity执行Acitivity.performCreate方法
大结局
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
//最后回调onCreate方法
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
到这里就分析完了整个App的启动流程啦!
网友评论