App啟動(dòng)簡單流程描述
- 在手機(jī)上點(diǎn)擊App的快捷圖標(biāo)萤衰,此時(shí)手機(jī)屏幕就是一個(gè)Activity堕义,而這個(gè)Activity所在的APP,業(yè)界稱為launchActivity
- 當(dāng)我們自己開發(fā)一款A(yù)PP的時(shí)候脆栋,AndvoidManifest一般會(huì)這么寫來啟動(dòng)默認(rèn)Activity
<activity
android:name=".login.LuanchActivity"
android:screenOrientation="portrait"
android:theme="@style/SplashAppTheme"
android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- Launch中為每個(gè)App圖標(biāo)提供了啟動(dòng)這個(gè)App所需要的Intent信息,這些信息是App安裝或者啟動(dòng)的時(shí)候倦卖,PackManagerService從自己的apk包的Manifest文件中讀取到的,所以點(diǎn)擊圖標(biāo)就會(huì)啟動(dòng)了自己的app的引導(dǎo)頁或者首頁
App啟動(dòng)流程
我們會(huì)發(fā)現(xiàn):Launcher和自己的APP(假設(shè)App名為為測試),它們位于不同的進(jìn)程中椿争,它們之間的通信是通過Binder完成——這時(shí)候ActivityManagerService(AMS)就起到了至關(guān)重要
以啟動(dòng)demo為例怕膛,整體流程分為7個(gè)階段
- 1.Launcher通知AMS,要啟動(dòng)測試App,而且指定要啟動(dòng)App的哪個(gè)頁面(也就是AndvoidManifest中設(shè)置的首頁)
- 2.AMS通知Launcher,"好了秦踪,我知道了嘉竟,沒你什么事情了“,同時(shí)記住要啟動(dòng)的首頁
- 3.Launcher當(dāng)前頁面進(jìn)入Paused狀態(tài)洋侨,通知AMS,“我睡了倦蚪,你可以去找測試App了”
- 4.AMS檢查測試App是否已經(jīng)啟動(dòng)希坚,是,則喚起測試App即可陵且,否裁僧,就要啟動(dòng)一個(gè)新的進(jìn)程,AMS在新的進(jìn)程創(chuàng)建一個(gè)ActiivtyThread,啟動(dòng)其中的main函數(shù)
- 5.測試App啟動(dòng)后慕购,通知AMS聊疲,“我啟動(dòng)好了”
- 6.AMS找到第二步存放的值,告訴測試APP沪悲,啟動(dòng)哪個(gè)頁面
- 7.測試App啟動(dòng)首頁获洲,創(chuàng)建context并與首頁Activity關(guān)聯(lián),然后調(diào)用Activity的onCreate方法
至此啟動(dòng)流程完成殿如,可分成兩部分:第1~3階段贡珊,Launcher和AMS相互通信;第4~7階段涉馁,測試App和AMS相互通信
Activity啟動(dòng)流程源碼(源碼是API25)
第一階段:Launcher通知AMS
- 第1步和第2步—點(diǎn)擊圖標(biāo)啟動(dòng)APP:點(diǎn)擊Launcher上的測試APP的快捷圖標(biāo)门岔,這時(shí)候會(huì)調(diào)用Launcher的startActIvitySafely方法,其實(shí)還是會(huì)調(diào)用Activity的startActivity方法,intent中帶著要啟動(dòng)測試App所需要的如下關(guān)鍵信息:
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
cmp="com.test.activity.LaunchActivity"
我們看Activity中的startActivity方法
@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);
}
}
startActivityForResult的源碼
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
requestCode為-1烤送,表示Launcher并不關(guān)心測試App是否啟動(dòng)成功返回的結(jié)果
- 第三步:startActivityForResult寒随,對(duì)上面代碼繼續(xù)往下走
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
//...代碼省略
}
我們可以看到有個(gè)mMainThread的變量,這是一個(gè)ActivityThread類型的變量,
ActivityThread,就是主線程,也就是UI線程妻往,它是在App啟動(dòng)時(shí)創(chuàng)建的互艾,它代表了App應(yīng)用程序。而Application實(shí)際只是整個(gè)ActivityThread的上下文
這里需要注意兩個(gè)參數(shù):mMainThread.getApplicationThread(),和mToken
1.通過ActivityThread中的getApplicationThread方法取到一個(gè)binder對(duì)象,這個(gè)對(duì)象的類型為ApplicationThread蒲讯,代表launcher所在的APP進(jìn)程
2.mToken也是一個(gè)Binder對(duì)象忘朝,代表Launcher這個(gè)Activity也通過mInstrumentation傳遞給AMS,AMS一查就知道誰像AMS發(fā)送請(qǐng)求
這兩個(gè)參數(shù)是伏筆判帮,傳遞給AMS局嘁,以后AMS想反過來通知Launcher,就能通過這兩個(gè)參數(shù)找到Launcher晦墙。
- 第四步悦昵,Instrumentation.execStartActivity源碼分析(Instrumentation可以幫我們找到我們要啟動(dòng)的activity)
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 = ActivityManagerNative.getDefault()
.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;
}
實(shí)際做的就是借助Instrumentation,把Activity數(shù)據(jù)傳遞給ActivityManagerNative(AMN)
- 第五步AMN的getDefault方法(API26以后是getService,并且沒有AMN的代理對(duì)象ActivityManagerProxy)
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
}
ServiceManager是一個(gè)容器類晌畅,AMN通過getDefault方法但指,從ServiceManager獲得一個(gè)對(duì)象
IBinder b = ServiceManager.getService("activity")
然后把它封裝成一個(gè)ActivityMangerProxy對(duì)象(AMP)
IActivityManager是一個(gè)實(shí)現(xiàn)了IInterface的接口,里面定義了四大組件所有的生命周期和常用方法抗楔,比如startActivity棋凳。
- 第六步——AMP的startActivity方法。
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
實(shí)際就是寫數(shù)據(jù)到另一個(gè)進(jìn)程,也就是AMS连躏,然后等待AMS返回結(jié)果
第二階段:AMS處理Launcher傳過來的信息
接著上面剩岳,看上面AMP的startActivity源碼
- Binder(也就是AMN/AMP)和AMS通信,當(dāng)啟動(dòng)自己的APP的時(shí)候會(huì)將會(huì)發(fā)送類型START_ACTIVITY請(qǐng)求給AMS入热, 同時(shí)告訴AMS啟動(dòng)哪個(gè)Activity
- AMS會(huì)去檢查自己App中的Manmifest文件拍棕,是否存在要啟動(dòng)的APP,如果不存在勺良,就拋出Activity Not found錯(cuò)誤
- AMS通知Launcher绰播,“沒你什么事情了,你休息吧”
AMS通過ApplicationThreadProxy發(fā)送消息尚困,而App端則通過ApplicationThread來接收這個(gè)消息蠢箩。
第三階段:Launcher去休眠,然后通知AMS:“我真的已經(jīng)睡了”
接下來將是一頓操作去尋找代碼,我只貼主要的流程代碼,首先由上面分析我們可以知道最終到的是ActivityManagerService中的startActivity方法
@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);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}
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, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
// PackageManagerService-----> 掃描app事甜,注冊(cè)組件
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
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);
}
final 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) {
// 驗(yàn)證intent忙芒、Class、Permission等
// 保存將要啟動(dòng)的Activity的Record
err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true, options, inTask);
return err;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
// 檢查將要啟動(dòng)的Activity的launchMode和啟動(dòng)Flag
// 根據(jù)launcheMode和Flag配置task
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask);
// 舉一個(gè)例子 SingleTop
if (dontStart) {
top.deliverNewIntentLocked(
mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
// Don't use mStartActivity.task to show the toast. We're not starting a new activity
// but reusing 'top'. Fields in mStartActivity may not be fully initialized.
mSupervisor.handleNonResizableTaskIfNeeded(
top.task, preferredLaunchStackId, topStack.mStackId);
return START_DELIVERED_TO_TOP;
}
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
if (mDoResume) {
//看這個(gè)
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
}
ActivityStackSupervirsor
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
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);
}
return false;
}
實(shí)際調(diào)用的是ActivityStack的resumeTopActivityUncheckedLocked
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//代碼省略
boolean result = false;
try {
//代碼省略
result = resumeTopActivityInnerLocked(prev, options);
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//代碼省略
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
}
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean dontWait) {
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
//主要這個(gè)
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
// 代碼省略
}
}
}
prev.app.thread實(shí)際是ActivityThread也就是說實(shí)際調(diào)用的是ActivityThread中的schedulePauseActivity方法
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
ApplicationThread(APT)接受到AMS消息后讳侨,調(diào)用ActivityThread的sendMessage方法呵萨,向Launcher的主線程消息隊(duì)列發(fā)送一個(gè)PAUSE_ACTIVITY消息
我們都知道Hnadler會(huì)調(diào)用handlerMessager,繼續(xù)走
public void handleMessage(Message msg) {
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
handlePauseActivity源碼
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
return;
}
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
handlePauseActivity主要做兩件事情
- ActvityThread有一個(gè)mActivities集合跨跨,保存當(dāng)前App也就是launcher中所有打開的 Activity潮峦,把它找出來囱皿,然后讓它休眠
- 通過AMP通知AMS,“我真的休眠了”
第四階段:AMS啟動(dòng)新的進(jìn)程
AMS要啟動(dòng)測試App,因?yàn)楹笈_(tái)進(jìn)程沒有該APP忱嘹,所以要啟動(dòng)一個(gè)新的進(jìn)程嘱腥,并且制定ActvityThread的main函數(shù)為入口函數(shù)。這階段了解即可
第五階段:新的進(jìn)程啟動(dòng)拘悦,以ActivityThread的main函數(shù)作為入口
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
//初始化應(yīng)用系統(tǒng)中的路徑
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
//設(shè)置進(jìn)程的名字
Process.setArgV0("<pre-initialized>");
//創(chuàng)建looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.attach方法
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//代碼省略
}
}
實(shí)際調(diào)用的AMS中的attachApplication方法
ActivityManagerService中的方法:
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
attachApplicationLocked代碼較長直接截取(這行需要注意下面還會(huì)分析第二個(gè)方法)
AMS中的方法齿兔,主要功能有以下兩步
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
//代碼省略
主要用于創(chuàng)建Application,用調(diào)用onCreate方法
thread.bindApplication(...);
//代碼省略
//主要用于創(chuàng)建Activity
if (mStackSupervisor.attachApplicationLocked(app)) {
//代碼省略
}
}
此時(shí)回到ActivityThread的bindApplication方法其實(shí)里面主要是這個(gè)方法
sendMessage(H.BIND_APPLICATION, data);
//handlermessage中的方法
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;
AppBindData會(huì)創(chuàng)建一個(gè)loadapk對(duì)象,標(biāo)記當(dāng)前APK信息
handleBindApplication源碼
private void handleBindApplication(AppBindData data) {
try {
//其他省略直接看這行,實(shí)際調(diào)用的LoadApk中的makeApplication方法
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
}
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
try {
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
}
if (instrumentation != null) {
try {
//這行源碼就不看了實(shí)際就是調(diào)用onCreate方法
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
//代碼省略
}
}
}
//newApplication最終走到這里,實(shí)際就是通過反射創(chuàng)建Application對(duì)象
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
回到剛才attachApplicationLocked中的源碼mStackSupervisor.attachApplicationLocked(app)源碼
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
//代碼省略
if (realStartActivityLocked(hr, app, true, true)) {
//代碼省略
}
//代碼省略
}
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//代碼省略
try {
調(diào)用ApplicationThread的scheduleLaunchActivity用于啟動(dòng)一個(gè)Activity
app.thread.scheduleLaunchActivity(...);
} catch (RemoteException e) {
}
}
1)創(chuàng)建一個(gè)主線程Looper础米,也就是MainLooper分苇。注意,MainLooper就是在這里創(chuàng)建的屁桑。
2)創(chuàng)建Application医寿。注意,Application是在這里生成的蘑斧。
主線程在收到BIND_APPLICATION消息后靖秩,根據(jù)傳遞過來的ApplicationInfo創(chuàng)建一個(gè)loadApk對(duì)象(標(biāo)記當(dāng)前APK信息),然后創(chuàng)建ContextImpl對(duì)象(標(biāo)志當(dāng)前進(jìn)程的環(huán)境),緊接著通過反射創(chuàng)建目標(biāo)Application竖瘾,并調(diào)用其attach方法沟突,將ContextImpl對(duì)象設(shè)置為目標(biāo)Application的上下文環(huán)境,最后調(diào)用Application的onCreate函數(shù)捕传,做一些初始工作事扭。
第六階段:AMS告訴新APP啟動(dòng)哪個(gè)Activity
AMS把傳入ActivityThread對(duì)象轉(zhuǎn)換成ApplicationThread對(duì)象,用于以后和這個(gè)App跨進(jìn)程通信
在第一階段乐横,Launcher通知AMS,要啟動(dòng)測試APP的哪個(gè)Activity今野,在第二階段葡公,這個(gè)信息AMS保存下來,第六階段条霜,AMS從過去的記錄中翻出要啟動(dòng)哪個(gè)Activity,通過APT告訴app
第七階段:啟動(dòng)測試App的首頁Activity
回到剛才的第五階段接著分析app.thread.scheduleLaunchActivity(的源碼催什,實(shí)際是ActivityThread的scheduleLaunchActivity,里面實(shí)際就是發(fā)送了個(gè)消息
sendMessage(H.LAUNCH_ACTIVITY, r);
//handlerMessage中查看
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;
ActivityClientRecord 是AMS傳遞過來的要啟動(dòng)的Activity
getPackageInfoNoCheck方法宰睡,這個(gè)方法會(huì)提取apk中的所有資源蒲凶,然后設(shè)置r的packageInfo屬性。
handleLaunchActivity源碼分析
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//代碼省略
Activity a = performLaunchActivity(r, customIntent);
//代碼省略
}
//performLaunchActivity源碼
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//通過反射獲得activity的實(shí)列
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.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) {
//代碼省略
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//為activity創(chuàng)建一個(gè)上下文
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//將上下文傳給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);
//代碼省略
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
//代碼省略
return activity;
}
1)通過Instrumentation的newActivity方法拆内,創(chuàng)建要啟動(dòng)的Activity實(shí)例旋圆。
2)為這個(gè)Activity創(chuàng)建一個(gè)上下文Context對(duì)象,并與Activity進(jìn)行關(guān)聯(lián)麸恍。
3)通過Instrumentation的callActivityOnCreate方法灵巧,執(zhí)行Activity的onCreate()方法搀矫,從而啟動(dòng)Activity。
參考書籍:<<android插件化開發(fā)指南>>