轉(zhuǎn)載請(qǐng)注明文章出處LooperJing!
在上一篇博客http://www.reibang.com/p/98fa08ee1bfb玖绿,我們起碼知道了Zygote是怎么啟動(dòng)SystemServer進(jìn)程的褥紫,AMS是怎么注冊(cè)的缤沦,啟動(dòng)的色鸳,啟動(dòng)之后通過(guò)Socket怎樣與Zygote進(jìn)程通信的脾拆,而Zygote進(jìn)程收到AMS的請(qǐng)求之后财异,是怎么fork進(jìn)程劳跃,將ActivityThread的main方法是執(zhí)行起來(lái)的观腊。這些內(nèi)容在我的前兩篇博客都梳理過(guò)邑闲,建議閱讀一下,在看本文恕沫。
一监憎、Activity請(qǐng)求啟動(dòng)
我們以startActivity這種來(lái)分析
Intent intent=new Intent(MainActivity.this,TargetActivity.class);
startActivity(intent);
經(jīng)過(guò)startActivity-->startActivityForResult-->execStartActivity,最終會(huì)調(diào)用Instrumentation的execStartActivity方法。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
.....
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//獲取AMS的代理婶溯,啟動(dòng)Activity
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//檢查Activity是否啟動(dòng)成功鲸阔,若失敗給出是什么原因
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
這些參數(shù)的意思是
- this,為啟動(dòng)Activity的對(duì)象迄委;
- contextThread褐筛,為Binder對(duì)象,是主進(jìn)程的context對(duì)象叙身;
- token渔扎,也是一個(gè)Binder對(duì)象,指向了服務(wù)端一個(gè)ActivityRecord對(duì)象信轿;
- target晃痴,為啟動(dòng)的Activity;
- intent财忽,啟動(dòng)的Intent對(duì)象倘核;
- requestCode,請(qǐng)求碼即彪;
- options紧唱,參數(shù);
先看checkStartActivityResult方法的實(shí)現(xiàn)
public static void checkStartActivityResult(int res, Object intent) {
if (res >= ActivityManager.START_SUCCESS) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
throw new IllegalStateException(
"Session calling startVoiceActivity does not match active session");
case ActivityManager.START_VOICE_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start voice activity on a hidden session");
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
```
常見的ActivityNotFoundException隶校,SecurityException等錯(cuò)日志就在這里報(bào)出來(lái)的漏益。
OK,現(xiàn)在回到execStartActivity深胳,內(nèi)部調(diào)用了ActivityManagerNative.getDefault().startActivity绰疤,關(guān)于ActivityManagerNative已經(jīng)說(shuō)了很多了,相當(dāng)于AMS服務(wù)端存根或者代理稠屠,其客戶端是ActivityManagerNative的內(nèi)部類ActivityManagerProxy峦睡,這里getDefault獲取的就是ActivityManagerProxy對(duì)象翎苫,通過(guò)ActivityManagerProxy對(duì)象來(lái)使用AMS內(nèi)部的一些服務(wù),包括單不限于啟動(dòng)Activity榨了。所以通過(guò)ActivityManagerProxy對(duì)象調(diào)用startActivity方法的實(shí)質(zhì)是調(diào)用BinderProxy.transact向Binder驅(qū)動(dòng)發(fā)送START_ACTIVITY_TRACSACTION命令煎谍,binder驅(qū)動(dòng)將處理邏輯從Launcher所在的進(jìn)程切換到AMS所在的SystemServer進(jìn)程。OK龙屉,我們直接看ActivityManagerService的startActivity方法呐粘,不明白,建議看一下Binder的通信原理转捕。
####二作岖、AMS處理Activity的啟動(dòng)請(qǐng)求
#####2.1、AMS處理Activity的啟動(dòng)請(qǐng)求
@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());
}
保持篇幅五芝,以下步驟省略痘儡。
ActvityiManagerService.startActivityAsUser()
ActivityStackSupervisor.startActivityMayWait()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.startActivityUncheckedLocked()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStackSupervisor.resumeTopActivityInnerLocked()
在resumeTopActivityInnerLocked的內(nèi)部有如下代碼。
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
這表明在啟動(dòng)一個(gè)Activity的時(shí)候枢步,前面一個(gè)Activity要執(zhí)行onPause方法沉删,onPause方法是怎么調(diào)用的呢?
#####2.2醉途、AMS調(diào)用棧頂Activity的onPause
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
......
if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
prev.updateThumbnailLocked(screenshotActivities(prev), null);
}
stopFullyDrawnTraceIfNeeded();
mService.updateCpuStats();
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
//調(diào)用ApplicationThread的schedulePauseActivity
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
......
}
}
......
}
這里先留一個(gè)問(wèn)題矾瑰, 我知道prev.app.thread是ApplicationThreadProxy對(duì)象,實(shí)際是調(diào)用了ApplicationThread的schedulePauseActivity方法隘擎,但是**AMS是怎么獲取到prev.app.thread的呢殴穴?**
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
configChanges);
}
關(guān)鍵就是最后調(diào)用了sendMessage(H.BIND_APPLICATION, data),發(fā)送了消息。關(guān)于H這個(gè)類货葬,其實(shí)是個(gè)Hander采幌,我覺(jué)得它的作用就像是一個(gè)交通樞紐。對(duì)這個(gè)H想更詳細(xì)了解的震桶,詳細(xì)[戳我](http://www.reibang.com/p/325d3cd79fd5)植榕。H接收到這個(gè)Message之后,調(diào)用
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&2) != 0);
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
.......
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb());
.......
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
mSomeActivitiesChanged = true;
}
}
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
if (r.paused) {
.......
try {
.......
//調(diào)用Instrumentation的callActivityOnPause方法
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
.......
}
}
r.paused = true;
.......
return !r.activity.mFinished && saveState ? r.state : null;
}
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
//onPause執(zhí)行
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
分析到這里 onPause()終于執(zhí)行了尼夺。回到 handlePauseActivity方法中炒瘸,在這個(gè)方法最后調(diào)用了ActivityManagerNative.getDefault().activityPaused(token)
#####2.3淤堵、ActivityManagerService的activityPaused方法執(zhí)行。
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
經(jīng)過(guò)一些方法顷扩,最終會(huì)調(diào)用startSpecificActivityLocked
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked ()
ActivityStack.startSpecificActivityLocked ()
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);
}
如果需要啟動(dòng)的Activity所需要的應(yīng)用進(jìn)程是否已經(jīng)啟動(dòng)拐邪,如果沒(méi)有則執(zhí)行realStartActivityLocked去啟動(dòng)Activity,否則去啟動(dòng)啟動(dòng)應(yīng)用進(jìn)程,相當(dāng)于一個(gè)預(yù)啟動(dòng)的過(guò)程隘截。
#####2.4扎阶、應(yīng)用進(jìn)程創(chuàng)建
關(guān)于startProcessLocked怎么執(zhí)行的汹胃,上篇博客分析過(guò),SystemServer進(jìn)程中Ams通過(guò)Socket與Zygote進(jìn)程進(jìn)行通信的东臀,Zygote接收到AMS發(fā)起的創(chuàng)建進(jìn)程的請(qǐng)求着饥,會(huì)fork出一個(gè)子進(jìn)程,并且反射調(diào)用這個(gè)進(jìn)程中ActivityThread的main方法惰赋。詳情步驟[戳我](http://www.reibang.com/p/98fa08ee1bfb),在應(yīng)用進(jìn)程啟動(dòng)之后宰掉,ActivityThread的main方法就開始執(zhí)行了。
####三赁濒、ActivityThread的main方法執(zhí)行
在ActivityThread的main方法里調(diào)用thread.attach(false);
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
......
Process.setArgV0("<pre-initialized>");
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");
}
對(duì)于上面main方法轨奄,相信很多人都看多很多遍了,接下來(lái)重點(diǎn)分析 thread.attach(false)這行代碼拒炎。
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
.......
//獲取ActivityManagerService在客戶端的代理
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//實(shí)質(zhì)是調(diào)用ActivityManagerService的attachApplication方法,目的是讓ActivityManagerService通過(guò)ApplicationThread代理對(duì)象控制應(yīng)用進(jìn)程
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}
}
.......
}
在調(diào)用 mgr.attachApplication()的時(shí)候挪拟,將mAppThread對(duì)象傳進(jìn)去了。
final ApplicationThread mAppThread = new ApplicationThread();
ApplicationThread繼承了ApplicationThreadNative击你, 看一下ApplicationThreadNative里面的方法玉组。

內(nèi)部調(diào)用了ActivityManagerNative.getDefault() .attachApplication,關(guān)于ActivityManagerNative已經(jīng)說(shuō)了很多了果漾,相當(dāng)于AMS服務(wù)端存根或者代理球切,其客戶端是ActivityManagerNative的內(nèi)部類ActivityManagerProxy,這里getDefault獲取的就是ActivityManagerProxy對(duì)象绒障,通過(guò)ActivityManagerProxy對(duì)象來(lái)使用AMS內(nèi)部的一些服務(wù)吨凑,包括單不限于啟動(dòng)Activity。所以通過(guò)ActivityManagerProxy對(duì)象調(diào)用attachApplication方法的實(shí)質(zhì)是調(diào)用BinderProxy.transact向Binder驅(qū)動(dòng)發(fā)送ATTACH_APPLICATION_TRANSACTION命令户辱,binder驅(qū)動(dòng)將處理邏輯從APP應(yīng)用進(jìn)程所在的進(jìn)程切換到AMS所在的SystemServer進(jìn)程鸵钝。OK,我們直接看ActivityManagerService的attachApplication方法:
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
//通過(guò)進(jìn)程ID庐镐,獲取進(jìn)程的記錄信息
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
if (app == null) {
Slog.w(TAG, "No pending application record for pid " + pid
+ " (IApplicationThread " + thread + "); dropping process");
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
if (pid > 0 && pid != MY_PID) {
//如果沒(méi)有獲取到恩商,需要?dú)⑺涝撨M(jìn)程,MY_PID是系統(tǒng)進(jìn)程
Process.killProcessQuiet(pid);
} else {
......
return false;
}
......
//獲取進(jìn)程名稱
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;
}
EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
//設(shè)置進(jìn)程的OOM必逆,adj等值
//還記得上面留下的那個(gè)問(wèn)題嗎怠堪,AMS是怎么獲取到prev.app.thread的呢?就在這名眉,prev.app是ProcessRecord對(duì)象粟矿,makeActive內(nèi)部將thread對(duì)象賦值給prev.app.thread∷鹇#可以自己查閱陌粹,這樣AMS是可以查詢進(jìn)程記錄的,進(jìn)程記錄中就有一個(gè)app.thread福压,若AMS要跟Activity通信直接獲取prev.app.thread就可以了掏秩。
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
//將attach之前的超時(shí)Meessage移除掉
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
......
try {
......
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) {
// todo: Yikes! What should we do? For now we will try to
// start another process, but that could easily get us in
// an infinite loop of restarting processes...
Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
}
......
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// 執(zhí)行等待進(jìn)程而暫時(shí)掛起的Service
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
// 執(zhí)行等待進(jìn)程而暫時(shí)掛起的廣播
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;
}
}
......
if (!didSomething) {
//調(diào)整進(jìn)程優(yōu)先級(jí)adj的值
updateOomAdjLocked();
}
return true;
}
發(fā)現(xiàn)AMS用IApplicationThread對(duì)象thread調(diào)用了bindApplication或舞,thread實(shí)際上就是ApplicationThreadProxy對(duì)象。AMS通過(guò)ApplicationThreadProxy對(duì)象與ActivityThread通信蒙幻。所以去ApplicationThread中看bindApplication的真正實(shí)現(xiàn)映凳。
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
......
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
這里又是用H發(fā)送了一個(gè)消息,是不是很像一個(gè)交通樞紐杆煞,做轉(zhuǎn)發(fā)用的魏宽。詳細(xì)[戳我](http://www.reibang.com/p/325d3cd79fd5)。
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
handleBindApplication內(nèi)部就不分析了决乎,Applcation對(duì)象的onCreate方法調(diào)用就是在這里面队询,它內(nèi)部創(chuàng)建了Applcation對(duì)象。
####四构诚、Activity周期如何執(zhí)行
#####蚌斩、4.1、Activity的onCreate是怎么回調(diào)的
回到第二小節(jié)的startSpecificActivityLocked方法
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)) {
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);
}
在預(yù)啟動(dòng)之后范嘱,一般我們的應(yīng)用進(jìn)程就被孵化來(lái)了送膳,直接執(zhí)行realStartActivityLocked去啟動(dòng)Activity。
在realStartActivityLocked內(nèi)部調(diào)用了如下代碼丑蛤,現(xiàn)在你應(yīng)該知道 app.thread是什么了叠聋。
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);
直接到scheduleLaunchActivity真正實(shí)現(xiàn),它的真正實(shí)現(xiàn)是在Applciation中的受裹。
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);
}
經(jīng)過(guò)一堆的變量賦值之后碌补,又通過(guò)H發(fā)送了一個(gè)消息LAUNCH_ACTIVITY,H在收到這個(gè)消息之后棉饶,執(zhí)行下面厦章。
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// Initialize before creating the activity
WindowManagerGlobal.initialize();
//一個(gè) perform開頭的方法,啟動(dòng)Activity
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
//Launch
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
if (!r.activity.mFinished && r.startsNotResumed) {
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
.....
}
r.paused = true;
}
.....
}
}
這個(gè)方法會(huì)將Activity創(chuàng)建出來(lái)照藻。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
r.activityInfo.targetActivity);
......
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
.......
} catch (Exception e) {
.......
}
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (activity != null) {
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);
.......
//Activity的create方法執(zhí)行
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
.......
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
//Activity的start方法執(zhí)行
activity.performStart();
r.stopped = false;
}
mActivities.put(r.token, r);
return activity;
}
反射創(chuàng)建Activity袜啃,為啥要用反射呢,此處搞不清楚幸缕。
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
解析來(lái)mInstrumentation調(diào)用callActivityOnCreate方法群发。
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
final void performCreate(Bundle icicle) {
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
onCreate方法在此處被調(diào)用了。
#####4.2发乔、Activity的onStart是怎么回調(diào)的
在performLaunchActivity中調(diào)用了callActivityOnCreate之后也物,又會(huì)調(diào)用 activity.performStart()
final void performStart() {
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
mFragments.noteStateNotSaved();
mCalled = false;
mFragments.execPendingActions();
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
mFragments.dispatchStart();
mFragments.reportLoaderStart();
mActivityTransitionState.enterReady(this);
}
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
到此處start方法又被調(diào)用了。
#####4.3列疗、Activity的onResume是怎么回調(diào)的
handleLaunchActivity方法中,在調(diào)用performLaunchActivity之后浪蹂,調(diào)用了handleResumeActivity方法抵栈。
ActivityThread.handleResumeActivity()
ActivityThread.handleResumeActivity()
Activity.performResume()
Instrumentation.callActivityOnResume();
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
到此Activity的onResume方法被調(diào)用告材,onPause方法已經(jīng)講解過(guò),關(guān)于onStop古劲,onDestory一樣的套路分析斥赋。
#####五、總結(jié)
關(guān)于Activity的啟動(dòng)過(guò)程分析产艾,三篇文章都分析完了疤剑,現(xiàn)在以一張圖總結(jié)一下。

- 啟動(dòng)一個(gè)Activity的方式有多種闷堡,都是通過(guò)向Ams發(fā)送startActivity請(qǐng)求
- Ams在啟動(dòng)Activity的時(shí)候隘膘,會(huì)判斷目標(biāo)進(jìn)程有沒(méi)有被創(chuàng)建,沒(méi)有創(chuàng)建的話杠览,向zygote進(jìn)程發(fā)送創(chuàng)建進(jìn)程的請(qǐng)求弯菊;
- Zygote進(jìn)程fork出新的子進(jìn)程,即App進(jìn)程踱阿;
- App進(jìn)程管钳,通過(guò)Binder IPC向sytem_server進(jìn)程發(fā)起attachApplication請(qǐng)求;
- AMS所在的SystemServer進(jìn)程在收到請(qǐng)求后软舌,進(jìn)行一系列準(zhǔn)備工作后才漆,再通過(guò)binder IPC向App進(jìn)程發(fā)送scheduleLaunchActivity請(qǐng)求;
- App進(jìn)程的binder線程(ApplicationThread)在收到請(qǐng)求后佛点,通過(guò)handler向主線程發(fā)送LAUNCH_ACTIVITY消息醇滥;
- 主線程在收到Message后,通過(guò)發(fā)射機(jī)制創(chuàng)建目標(biāo)Activity恋脚,并回調(diào)Activity.onCreate()等方法腺办。
上圖大致說(shuō)明了一個(gè)Activity的啟動(dòng)流程, 重點(diǎn)在于把握Binder的通信原理糟描,接著弄清楚APP進(jìn)程怀喉,SystemServer進(jìn)程,Zygote進(jìn)程是怎么互相通信的船响。seeyou!
參考博客:
http://gityuan.com/2016/03/12/start-activity/