注册

Android四大组件的启动分析与整理(一):Activity的启动过程



前言


换工作后,一直忙,没时间整理,逼自己一把吧,目标一周整理出来,理顺思路,这里先起个头。


首先Activity的启动分两种,一种是根Activity的启动,另一种是普通Activity的启动,根Activity的启动,从LauncherActivity开始,启动方式跟我们平时的startActivity是基本一样的。


public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
。。。。。。。。。。。
//设置flag为new task
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
。。。。。。。。。。。
if (Utilities.ATLEAST_MARSHMALLOW
&& (item instanceof ShortcutInfo)
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((ShortcutInfo) item).isPromise()) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
//通过startActivity开启
startActivity(intent, optsBundle);
} else {
LauncherAppsCompat.getInstance(this).startActivityForProfile(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
return true;
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}

当点击桌面的图标的时候,调用startActivitySafely(),然后先设置它的flag是new task,然后调用Activity的startActivity()方法,然后调用继续调用startActivityForResult(intent, -1, options);


	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,mParent肯定为null,Activity最终都会通过Instrumentation工具类去执行,这里就调用了execStartActivity()方法。


	public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String 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, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

instrumentation中通过调用ActivityManager.getService()方法,得到AMS,然后调用AMS中的startActivity方法继续执行。


    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;
}
};

这里需要注意一下,在Android8.0以前,都是通过ActivityManagerNative.getDefalt()方法,然后通过IActiv tyManager am= asinterface (b) ; 去获取AMS的代理类ActivityManagerProxy对象的。在asinterface 中直接new ActivityManagerProxy(b)并返回,8.0之后通过通过IActivityManager.Stub.asInterface(b)去获得,典型的AIDL写法AMS中也继承了IActivityManager.Stub。


@Override
public final int startActivity(.....) {
return startActivityAsUser(.....,UserHandle.getCallingUserId());
}
public final int startActivityAsUser(.....) {
enforceNotIsolatedCaller("startActivity");1
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),2
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");
}

(1)处判断调用者的进程是否被隔离,如果是就抛出SecurityException异常。
(2)处检查调用者是否有权限,如果没有也会抛出SecurityException异常。
然后继续调用ActivityStarter中的startActivityMayWait()方法,ActivityStarter是Activity的一个控制类,主要将flag和intent转为Activity,然后将Activity和task以及stack关联起来。


int startActivityLocked(...., String reason) {
if (TextUtils.isEmpty(reason)) {1
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
mLastStartActivityResult = startActivity(....);
if (outActivity != null) {
outActivity[0] = mLastStartActivityRecord[0];
}
return mLastStartActivityResult;
}

startActivityMayWait()方法很长,其中调用了startActivityLocked方法,(1)处就是之前传入的“startActivityAsUser”参数,用来说明调用原因,如果没有原因,抛出IllegalArgument异常,然后继续调用startActivity方法。


private int startActivity(IApplicationThread caller,.....ActivityRecord[] outActivity,.....) {
int err = ActivityManager.START_SUCCESS;
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
ProcessRecord callerApp = null;
if (caller != null) {1
//获取Launcher进程
callerApp = mService.getRecordForAppLocked(caller);//2
if (callerApp != null) {
//获取Launcher进程的pid和uid并赋值
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
Slog.w(TAG,.....);
err = ActivityManager.START_PERMISSION_DENIED;
}
}
...
//创建即将要启动的Activity的描述类ActivityRecord
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, container, options, sourceRecord);2
if (outActivity != null) {
outActivity[0] = r;3
}
...
doPendingActivityLaunchesLocked(false);
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);//4
}

这里首先在(1)处通过AMS的getRecordForAppLocked方法获取请求进程对象callerApp ,因为是从launcher启动,所以这里是launcher所在的进程,他是一个ProcessRecord对象,然后拿到pid和uid。
(2)处创建Activity信息,这样ProcessRecord和ActivityRecord就齐全了。继续startActivity;


    private int startActivityUnchecked(....) {
........
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);—————(1
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
.........
setTaskToCurrentTopOrCreateNewTask();
}
........
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mWindowManager.executeAppTransition();
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);————(2
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
.............
return START_SUCCESS;
}

(1)处通过setTaskFromReuseOrCreateNewTask()方法,创建TaskRecorder,这样一来,ProcessRecorder、ActivityRecorder以及TaskRecorder都齐全了,
(2)处调用resumeFocusedStackTopActivityLocked方法


    boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
return false;
}
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
mStackSupervisor.checkReadyForSleepLocked();
return result;
}

这里因为我们启动的是根Activity,那么topActivity肯定是为没有在running状态的,走的resumeTopActivityUncheckedLocked方法,然后执行resumeTopActivityInnerLocked方法。


    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
........
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
final boolean lastActivityTranslucent = lastStack != null
&& (!lastStack.mFullscreen
|| (lastStack.mLastPausedActivity != null
&& !lastStack.mLastPausedActivity.fullscreen));
..........
} else {
..........
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}

这里代码很多,最终执行的是ActivityStackSupervisor类中的startSpecificActivityLocked方法。


    void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
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)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);(1)
return;
} catch (RemoteException e) {
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);(2)
}

这里先获取启动进程ProcessRecord 然后调用realStartActivityLocked()方法;
如果ProcessRecorder进程为null那么就通过AMS的startProcessLocked去执行Process.start创建。


    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
..........
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
..........
return true;
}

其中app.thread其实就是ProcessRecorder的IApplicationManager,也就是ActivityThread的内部类ApplicationThread。
Activity启动过程其实就目标应用程序进程启动Activity的过程,这里的app就代表目标应用程序进程,那ApplicationThread继承了IApplicationThread.Stub就是目标应用程序与AMS进行binder通信的桥梁。
最后通知ApplicationThread调用scheduleLaunchActivity去启动Activity;


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) {
updateProcessState(procState, false);
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;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}

这里就是设置一堆属性,然后通过Activity的内部类H,其实就是handler类,发送LAUNCH_ACTIVITY消息,去执行


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;
----------------handleLaunchActivity------------------
Activity a = performLaunchActivity(r, customIntent);

然后调用handleLaunchActivity,然后继续调用performLaunchActivity,要执行一个Activity首先需要两个必备因素,一个是Context上下文,一个是Application。


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
.......................
ContextImpl appContext = createBaseContextForActivity(r);1
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);2
.......................
} catch (Exception e) {
.......................
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);3
if (activity != 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);4
.......................
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);5
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
.......................
return activity;
}

(1)处就是通过new ContextImpl的方式,创建Actviity的上下文。
(2)处就是通过反射的方式,创建Actviity类。
(3)处通过反射的方式,创建Application类,并把ContextImpl(这个上下文跟Activity的不一样,上面那个多了token和classloader)上下文attach到父类ContextWrapper中去,也就是mBase。
(4)有了ContextImpl和Application,然后将Actviity做attach操作,就是将ContextImpl给父类ContextWrapper中的mBase,同时创建PhoneWindow。
(5)处就是通过Instrumentation去调用oncreate方法
罗里吧嗦讲那么多,先去上个厕所,回来用一张图总结一下:


在这里插入图片描述



————————————————
版权声明:本文为CSDN博主「蒋八九」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/massonJ/article/details/117914286


0 个评论

要回复文章请先登录注册