Activity啟動(dòng)流程
本文章基于Android6.0源碼
1. Activity冷啟動(dòng)
冷啟動(dòng)表示啟動(dòng)的時(shí)候沒(méi)有沒(méi)有當(dāng)前應(yīng)用進(jìn)程箱舞,需要首先啟動(dòng)進(jìn)程,然后再啟動(dòng)當(dāng)前Activity或者Service嘀粱,或者BroadCastReceiver奠骄。
2. Activity熱啟動(dòng)
表示當(dāng)前應(yīng)用進(jìn)程已經(jīng)起來(lái),只需要直接啟動(dòng)一個(gè)Activity剩瓶,service就行驹溃,
3. Activity啟動(dòng)的流程圖
本圖基于Android6.0源碼,如有疑問(wèn)歡迎留言延曙,并且歡迎提出問(wèn)題豌鹤,可以一同解答。 其實(shí)對(duì)著當(dāng)前這個(gè)流程圖已經(jīng)大致將Activity啟動(dòng)流程進(jìn)行了反應(yīng)枝缔。
存在問(wèn)題:
- 目前缺少的是AMS通過(guò) Process.start 方法啟動(dòng)一個(gè)Process布疙, 這個(gè)Process是如何走到ActivityThread中去的
- **ActivityStackSupervisor.startSpecificActivityLocked **這個(gè)方法是怎么進(jìn)去的,這里的處理很多愿卸,目前也不是很明白
4. 關(guān)鍵代碼解析
4.1 Activity.startActivity
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
//這里就直接走到Instrumenttation類(lèi)灵临,來(lái)執(zhí)行Start
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) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
// ...忽略
}
}
4.2 Instrumentation.execStartActivity
Instrumentation 儀器,樂(lè)譜)類(lèi)是一個(gè)非常關(guān)鍵的類(lèi)趴荸, 在一個(gè)進(jìn)程中儒溉,Activity生命周期的操作,甚至Application的生命周期的操作都是通過(guò)它來(lái)執(zhí)行的发钝,可以說(shuō) 他就是APP生命活動(dòng)的 樂(lè)譜顿涣。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
//...省略一部分代碼
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.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;
}
這里 ActivityManagerNative.getDefault() 這個(gè)方法其實(shí)去獲取到ActivityManagerProxy,來(lái)拿到AMS的代理類(lèi)酝豪,通過(guò)Binder來(lái)執(zhí)行跨進(jìn)程調(diào)用园骆,這里就是第一次發(fā)生跨進(jìn)程調(diào)用的地方。
Activity進(jìn)程 ---> SystemServer 進(jìn)程
這里順便提一下寓调,AMS是怎么把自己加入到ServiceManager中的锌唾。
- ActivityManagerNative中是通過(guò) ServiceManager和activity名字來(lái)獲取到ActivityManagerProxy的client對(duì)象的。
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;
}
};
}
-
在AMS啟動(dòng)過(guò)程中,會(huì)調(diào)用一個(gè)**setSystemProcess ** 在這里晌涕,AMS會(huì)把自己添加到服務(wù)端里面滋捶。
public void setSystemProcess() { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this)); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this)); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); synchronized (this) { ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); app.persistent = true; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); synchronized (mPidsSelfLocked) { mPidsSelfLocked.put(app.pid, app); } updateLruProcessLocked(app, false, null); updateOomAdjLocked(); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find android system package", e); } }
4.3 AMS 執(zhí)行Activity啟動(dòng)
通過(guò)一次跨進(jìn)程Binder調(diào)用之后,AMS開(kāi)始執(zhí)行startActivity流程余黎。這里基本沒(méi)有什么. Android6.0 已經(jīng)將之前很多復(fù)雜的啟動(dòng)流程進(jìn)行了優(yōu)化(少了ActiivtyStarter,等等類(lèi))重窟,但是基本的流程是不變的。
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
4.4 ActivityStackSupervisor
ActivityStackSupervisor在真實(shí)啟動(dòng)Activity之前惧财,會(huì)針對(duì)Intent來(lái)進(jìn)行Resolve巡扇,將 Intent指向 的啟動(dòng)類(lèi) 通過(guò)PMS(PackageManagerServcie) 來(lái)解析出來(lái)。如果找不到響應(yīng)當(dāng)前Intent的類(lèi)垮衷,那么就會(huì)報(bào)啟動(dòng)異常
* 如果執(zhí)行錯(cuò)誤厅翔,會(huì)將錯(cuò)誤結(jié)果返回給 **Instrumentation** 調(diào)用 **checkStartActivityResult(result, intent);**
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 config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
// Collect information about the target of the Intent
//這里針對(duì)當(dāng)前的intentn進(jìn)行一次解析,涉及到了PMS(Actiivty安裝管理流程)
//如果這里針對(duì)intent解析沒(méi)有出來(lái)搀突, 就可能拋出異常表示沒(méi)有找到目標(biāo)Activity
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
ActivityContainer container = (ActivityContainer)iContainer;
// 這里解析之后刀闷,就執(zhí)行 startActivityLocked.
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
}
}
執(zhí)行startActivityLocked
這個(gè)方法比較長(zhǎng),但是發(fā)現(xiàn)Android源碼中一個(gè)比較好的點(diǎn)就是 一個(gè)方法中仰迁,前半段基本都是條件檢查甸昏,真正執(zhí)行的代碼一般都在最后。
這里的關(guān)鍵方法就是: startActivityUncheckedLocked
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage,
int realCallingPid, int realCallingUid, int startFlags, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
...
// 這里 省略的一段就是執(zhí)行 intent檢查徐许,看是否有目標(biāo)Actiivty響應(yīng) intet施蜜,或者啟動(dòng)Activity是否權(quán)限之類(lèi)的。
doPendingActivityLaunchesLocked(false);
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
if (err < 0) {
// If someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
// switch... just dismiss the keyguard now, because we
// probably want to see whatever is behind it.
notifyActivityDrawnForKeyguard();
}
return err;
}
執(zhí)行 startActivityUncheckedLocked
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
...
//這里前半段就是檢查當(dāng)前啟動(dòng)的activity棧是否存在雌隅,如果存在就直接將當(dāng)acitivyt進(jìn)行棧操作花墩。
mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
intent, r.getUriPermissionsLocked(), r.userId);
if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
}
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
}
ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
targetStack.mLastPausedActivity = null;
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
if (!launchTaskBehind) {
// Don't set focus on an activity that's going to the back.
mService.setFocusedActivityLocked(r, "startedActivity");
}
return ActivityManager.START_SUCCESS;
}
4.5 ActivityStack.startActivityLocked
現(xiàn)在這里就是執(zhí)行棧操作,并且將棧跟Window進(jìn)行關(guān)聯(lián)澄步。
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
···
// 上面省略的部分就是將當(dāng)前Stack和Window進(jìn)行關(guān)聯(lián)
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
4.6 ActivityStackSupervisor .startSpecificActivityLocked
這里就是關(guān)鍵的一步了冰蘑, 如果當(dāng)前要啟動(dòng)的Activity進(jìn)程已經(jīng)起來(lái)了,那么就直接啟動(dòng)Activity
否則就調(diào)用AMS啟動(dòng)進(jìn)程村缸。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.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);
}
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.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
4.7 AMS.startProcessLocked
這里主要三個(gè)任務(wù):
- 執(zhí)行檢查祠肥,看當(dāng)前包是否被凍結(jié)了,如果被凍結(jié)梯皿,那么就無(wú)法啟動(dòng)
- 啟動(dòng)Process
- 發(fā)送一個(gè)handler消息仇箱,用來(lái)定時(shí)檢查當(dāng)前Activity是否啟動(dòng)超時(shí)
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
try {
try {
if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
// This is caught below as if we had failed to fork zygote
throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (app.isolated) {
mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
}
mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
checkTime(startTime, "startProcess: done updating battery stats");
synchronized (mPidsSelfLocked) {
ProcessRecord oldApp;
// If there is already an app occupying that pid that hasn't been cleaned up
if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
// Clean up anything relating to this pid first
Slog.w(TAG, "Reusing pid " + startResult.pid
+ " while app is still mapped to it");
cleanUpApplicationRecordLocked(oldApp, false, false, -1,
true /*replacingPid*/);
}
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
checkTime(startTime, "startProcess: done updating pids map");
} catch (RuntimeException e) {
// XXX do better error recovery.
app.setPid(0);
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
Slog.e(TAG, "Failure starting process " + app.processName, e);
}
}
4.8 Process.start
這里就是第二次跨進(jìn)程調(diào)用了 ,但是這里這一次跨進(jìn)程通信用的就是Socket东羹,并不是Binder了剂桥。
SystemServer 進(jìn)程 ----> Zygote 進(jìn)程
Process.start方法可以說(shuō)是一個(gè)關(guān)鍵的步驟 這里就是通過(guò)Process 來(lái)用 Socket 跟Zygote進(jìn)程進(jìn)行通信, 通過(guò)socket命令属提,來(lái)執(zhí)行進(jìn)程的Fork权逗。
這里就可以看到包括SystemServer進(jìn)程美尸,Android系統(tǒng)中所有的進(jìn)程都是 zygote進(jìn)程孵化而來(lái), 這也就是 zygote 名字準(zhǔn)確性的體現(xiàn)斟薇。
這里涉及到Zygote進(jìn)程fork 進(jìn)程师坎,以及Socket通信就不在往下了,感興趣的可以繼續(xù)堪滨,下面列出幾個(gè)相關(guān)類(lèi):
ZygoteInit胯陋, LocalSocket,LocalSocketImpl
值得一提的是 在Linux中所有事件都是通過(guò)文件描述符來(lái)傳遞的, 因此Socket 其實(shí)也是基于文件描述符的袱箱。
4.9 ActivityThread啟動(dòng)
當(dāng)Zygote接受Socket命令遏乔,fork一個(gè)進(jìn)程之后,就走到 ActivityThread.main()方法 這里具體的 從4.8 ——> 4.9的更具體的細(xì)節(jié)我還沒(méi)搞懂发笔。
public static void main(String[] args) {
Environment.initForCurrentUser(); //這里也是執(zhí)行關(guān)鍵的一步盟萨,就是給當(dāng)前應(yīng)用創(chuàng)建 文件用戶操作文件夾
AndroidKeyStoreProvider.install();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper(); //準(zhǔn)備主線程 也就是Actiivty運(yùn)行的looper
ActivityThread thread = new ActivityThread();
thread.attach(false); //這里也是一個(gè)關(guān)鍵地方 這里一次 IApplicationThread綁定
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
ActivityThread.attach()
在Attach方法中,也進(jìn)行了一些關(guān)鍵處理筐咧,
- 將ApplicationThread 作為一個(gè) Server注冊(cè)到AMS中鸯旁,這樣 AMS就可以和當(dāng)前應(yīng)用進(jìn)行通信了
- RuntimeInit.setApplicationObject 這一句也是關(guān)鍵代碼噪矛,這里就涉及到 APPCrash的處理了
- 添加GC 回調(diào)量蕊,出現(xiàn)內(nèi)存不足時(shí)回收內(nèi)存
- 向ViewRootImpl中注冊(cè) Configchange的回調(diào)
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try { //這里又是一次跨進(jìn)程調(diào)用了
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} else {
}
DropBox.setReporter(new DropBoxReporter());
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
4.10 AMS.attachApplication
到這里障斋,目標(biāo)APP的進(jìn)程已經(jīng)起來(lái)了价匠,然后APP又會(huì)反過(guò)來(lái)將自己的Server注冊(cè)到AMS中,
這樣AMS就可以繼續(xù)執(zhí)行我們最初的目標(biāo)筒捺,StartActivity缩滨。
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); // 之前有發(fā)送進(jìn)程啟動(dòng)超時(shí)的檢查消息势就,這里已經(jīng)啟動(dòng)成功,所以進(jìn)行移除
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; //進(jìn)行contentProvider的 解析APP中的ContentProvider
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
try {
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
//這里也是一個(gè)關(guān)鍵步驟脉漏,又進(jìn)行了一次跨進(jìn)程Binder調(diào)用苞冯, 將事件回調(diào)給APp進(jìn)程,進(jìn)行APPlicaiton創(chuàng)建
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
return false;
}
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
// See if the top visible activity is waiting to run in this process...
//繼續(xù)我們未完成的事業(yè)侧巨,去啟動(dòng)Actiivty舅锄。
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// Find any services that should be running in this process...
//繼續(xù)我們未完成的事業(yè),去啟動(dòng)Service
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
// Check if a next-broadcast receiver is in this process...
// 繼續(xù)我們未完成的事業(yè)司忱,去進(jìn)行廣播接收
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// If the app died trying to launch the receiver we declare it 'bad'
Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
badApp = true;
}
}
// Check whether the next backup agent is in this process...
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
"New app is backup target, launching agent for " + app);
ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
badApp = true;
}
}
if (badApp) {
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
if (!didSomething) {
updateOomAdjLocked();
}
return true;
}
4.11 AMS 事件回調(diào)給Application
-
先看bindApplication //這里進(jìn)行了一次跨進(jìn)程皇忿, 然后跨線程調(diào)用
AMS --> Applicaiton 跨進(jìn)程
Applicaton binder線程 ----> ActivityThread 線程
private void handleBindApplication(AppBindData data) { //設(shè)置時(shí)區(qū) final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); // 創(chuàng)建 Instrumentation if (data.instrumentationName != null) { InstrumentationInfo ii = null; try { ii = appContext.getPackageManager(). getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { } if (ii == null) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = ii.nativeLibraryDir; mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); ApplicationInfo instrApp = new ApplicationInfo(); instrApp.packageName = ii.packageName; instrApp.sourceDir = ii.sourceDir; instrApp.publicSourceDir = ii.publicSourceDir; instrApp.splitSourceDirs = ii.splitSourceDirs; instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs; instrApp.dataDir = ii.dataDir; instrApp.nativeLibraryDir = ii.nativeLibraryDir; LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); //創(chuàng)建ContextImpl ContextImpl instrContext = ContextImpl.createAppContext(this, pi); try { java.lang.ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, data.instrumentationUiAutomationConnection); } else { mInstrumentation = new Instrumentation(); } // 這里 如果設(shè)置了標(biāo)志位,大內(nèi)存應(yīng)用坦仍,進(jìn)行一次清理 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); } else { dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); } // 創(chuàng)建Application try { Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; if (!data.restrictedBackupMode) { List<ProviderInfo> providers = data.providers; if (providers != null) { //創(chuàng)建ContentProvider對(duì)象 installContentProviders(app, providers); mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } } try { mInstrumentation.onCreate(data.instrumentationArgs); } //這里 通過(guò)Instrumentation 去調(diào)用Application的onCreate方法鳍烁,可以看道Contentprovider先于Application onCreate調(diào)用調(diào)用 try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { } } finally { StrictMode.setThreadPolicy(savedPolicy); } }
-
然后看 performLaunchActivity,這里performLaunch 其實(shí)也是一次跨進(jìn)程調(diào)用繁扎,ActivityThread已經(jīng)創(chuàng)建 ActivityStackSuperversior 通過(guò)持有的 ActivityThread對(duì)象幔荒,跨進(jìn)程調(diào)用一次,將調(diào)用 ActiivtyThread.handleLaunchActivity
AMS在跨進(jìn)程調(diào)用,使當(dāng)前進(jìn)程Application創(chuàng)建之后铺峭,墓怀,就回到我們之前的目的了,啟動(dòng)一個(gè)Activity卫键。
```java
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
```
-
重新回到 ActivityStackSupervisor
遍歷Display傀履, 然后選出display中的Stack, 選中Stack如果沒(méi)有要啟動(dòng)的Activity莉炉,那么就重新進(jìn)入Activity創(chuàng)建流程
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } ActivityRecord hr = stack.topRunningActivityLocked(null); if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + hr.intent.getComponent().flattenToShortString(), e); throw e; } } } } } return didSomething; }
-
進(jìn)入ActivityStackSupervisor.realStartActivityLocked
這里又是一次跨進(jìn)程調(diào)用钓账, 使用當(dāng)前綁定的ApplicationThread來(lái)主動(dòng)啟動(dòng)Activity,之后就進(jìn)入我們的Activity啟動(dòng)流程了絮宁。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { final ActivityStack stack = task.stack; try { if (app.thread == null) { throw new RemoteException(); } List<ResultInfo> results = null; List<ReferrerIntent> newIntents = null; if (andResume) { app.hasShownUi = true; app.pendingUiClean = true; } app.forceProcessStateUpTo(mService.mTopProcessState); //這里就用綁定的ApplicationThread對(duì)象來(lái)進(jìn)行跨進(jìn)程調(diào)用 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); } catch (RemoteException e) { if (r.launchFailed) { mService.appDiedLocked(app); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } app.activities.remove(r); throw e; } return true; }
接下來(lái)的流程就是執(zhí)行Actiivty的創(chuàng)建梆暮,執(zhí)行生命周期了。 我們之后接著分析绍昂。