為了寫這篇文章,我可是找了好些資料,看了好幾天才把其中關(guān)節(jié)順下來好清楚,資料很多,有說 app 冷啟動(dòng)的,有說從 Activity 啟動(dòng) Activity 的,還有說 window 加載頁面的,這些其實(shí)都時(shí)勾著的,一環(huán)套一環(huán),區(qū)別是有的時(shí)候有些環(huán)節(jié)不會(huì)跑。這里我從頭帶大家走一下,整個(gè)順一遍下來就都清楚了
app 冷啟動(dòng)是說從桌面啟動(dòng) app ,此時(shí)我們的應(yīng)用是沒有進(jìn)程的,需要?jiǎng)?chuàng)建。Activity 啟動(dòng) Activity,指的是進(jìn)程內(nèi)啟動(dòng)新的頁面,此時(shí)應(yīng)用進(jìn)程是存在的。系統(tǒng)桌面也是一個(gè) Activity ,名叫 Launch ,所以 app 冷啟動(dòng)和 Activity 啟動(dòng) Activity 差不多,走的都是 Activity 內(nèi)部的方法,區(qū)別就是先啟動(dòng)應(yīng)用進(jìn)程的事,這樣說大家就對這兩種啟動(dòng) Activity 的情況心里有數(shù)了
這塊必須清楚,因?yàn)槊嬖嚂r(shí)很多時(shí)候會(huì)問的,有的面試官會(huì)問你2者的關(guān)聯(lián),區(qū)別,簡單的自會(huì)問你 Activity 啟動(dòng)流程,你把2種 Activity 啟動(dòng)方式的關(guān)聯(lián)一說,絕對漲分。除了面試環(huán)節(jié)外,我們也能熟悉下系統(tǒng)流程,后面插件化會(huì)用到,另外也會(huì)對我們自己封裝框架,學(xué)習(xí)系統(tǒng)其他深入知識點(diǎn)有很大的幫助,比如 AIDL 雙向通訊,功能分割,代理分層,有助于我們以后看各種框架
app 的啟動(dòng)流程簡單來說:
- 用戶點(diǎn)擊 icon
- 系統(tǒng)開始加載和啟動(dòng)應(yīng)用
- 應(yīng)用啟動(dòng):開啟空白(黑色)窗口
- 創(chuàng)建應(yīng)用進(jìn)程
- 初始化Application
- 啟動(dòng) UI 線程
- 創(chuàng)建第一個(gè) Activity
- 解析(Inflater)和加載內(nèi)容視圖
- 布局(Layout)
- 繪制(Draw)
涉及系統(tǒng)類如下:
- Application
- Activity
- Instrumentation
- H
- ActivityThread
- IApplicationThread
- Instrumentation
- ActivityManagerService
- IActivityManager
- window
- ViewRootImpl
- 一對 AIDL 雙向通訊
IApplicationThread 和 IActivityManager 是一對配套的 AIDL 接口
- IActivityManager 負(fù)責(zé) Activity -> ActivityManagerService 的通訊
- IApplicationThread 負(fù)責(zé) ActivityManagerService -> Activity 的通訊
- 雙向通訊的綁定是在 Activity 拿到同 ActivityManagerService 通訊的 AIDL 時(shí)把自己的 IApplicationThread 也就是反向 AIDL 接口交給 ActivityManagerService ,這樣2者形成 AIDL 雙向通訊
- 功能分層,代碼類聚
若是按照 MVP 的思路來說:
- V 層是 widow ,負(fù)責(zé) Activity 界面的渲染
- P 層是 Instrumentation,封裝了 Activity 所有的操作邏輯,所有的操作邏輯入口都是在 Instrumentation 里面
- M 層是 ActivityThread ,ActivityThread 持有 Activity 和遠(yuǎn)程操作的 AIDL 交互接口
這么看的話,Activity 要清晰很多了,限于我小白的水平,估計(jì)有一些寫的不全,分析的疏漏的地方大家見諒呀~
正式開始
找到還可以的流程圖,方便后面比對


1. startActivity 我們?nèi)?dòng)一個(gè)新頁面
平時(shí)我們自己啟動(dòng) Activity 都是用的 startActivity 這個(gè)方法,那么對于 app 冷啟動(dòng),LaunchActivity 是怎么跑的?
看代碼,LaunchActivity 也沒多干什么事,LaunchActivity 會(huì)解析我們點(diǎn)擊圖標(biāo)對應(yīng)的 app 的配置文件,獲取期中信息構(gòu)建 intent ,然后再調(diào)用 startActivity
// 桌面點(diǎn)擊app圖標(biāo)
public void onClick(View v) {
...
Object tag = v . getTag ();
if (tag instanceof ShortcutInfo) {
onClickAppShortcut(v);
}
}
protected void onClickAppShortcut(final View v) {
...
// Start activities
startAppShortcutOrInfoActivity(v);
}
private void startAppShortcutOrInfoActivity(View v) {
ItemInfo item =(ItemInfo) v . getTag ();
Intent intent;
// 通過 PackageManagerService 解析 AndroidManifest.xml
if (item instanceof PromiseAppInfo) {
PromiseAppInfo promiseAppInfo =(PromiseAppInfo) item;
intent = promiseAppInfo.getMarketIntent();
} else {
intent = item.getIntent();
}
...
boolean success = startActivitySafely (v, intent, item);
...
}
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
...
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
startActivity(intent, optsBundle);
...
}
這樣 app 冷啟動(dòng)和 Activity 啟動(dòng) Activity 就聯(lián)系起來了,app 冷啟動(dòng)相比多了一步獲取目標(biāo) app 信息構(gòu)建 intent 過程,然后都會(huì)走 Activity.startActivity() 這
2. Activity.startActivity()
現(xiàn)在我們進(jìn)入 Activity 源碼里面了,源碼的話我們不用看的細(xì)節(jié),了解過程就成
Activity.startActivity() 調(diào)的是 startActivityForResult(), startActivityForResult() 方法會(huì)使用 mInstrumentation.execStartActivity()
//
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);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
3. mInstrumentation.execStartActivity
mInstrumentation 看過上面大家都知道了把,是 Activity 的 P 層,封裝了所有 Activity 的核心業(yè)務(wù)操作
mInstrumentation.execStartActivity 里面會(huì)調(diào) ActivityManager.startActivity ,ActivityManager 知道了吧,是 Activity 與 ActivityManagerService 的遠(yuǎn)程 AIDL 通訊類,并把反向 AIDL 通訊對象 ApplicationThread 傳給遠(yuǎn)程 ActivityManagerService , 方便 ActivityManagerService 回調(diào),這樣看 Activity 把創(chuàng)建 Activity 的任務(wù)交給了 遠(yuǎn)程 ActivityManagerService
//
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
...
// 這個(gè) whoThread 就是 ApplicationThread 反向 AIDL 通訊對象
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
...
} catch (RemoteException e) {
...
}
return null;
}
4. ActivityManagerService.startActivity
這是代碼 脫離 Ui 所在進(jìn)程來到了系統(tǒng) ActivityManagerService 進(jìn)程,ActivityManagerService 會(huì)怎么干呢,我們拭目以待
來看代碼
//
@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());
}
ActivityManagerService 的 startActivity 里面多次調(diào)用了其他方法:
- startActivity()
- -> ActivityStarter.startActivityMayWait()
- -> ActivityStarter.startActivityLocked()
- -> ActivityStarter.startActivity()
- -> ActivityStarter.startActivityUnchecked()
- -> ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
- -> ActivityStack.resumeTopActivityUncheckedLocked()
- -> ActivityStack.resumeTopActivityInnerLocked()
- -> ActivityStackSupervisor.startSpecificActivityLocked()
上面的這一柳方法一個(gè)調(diào)一個(gè),一直到在 tartSpecificActivityLocked 這個(gè)方法里才能看到核心內(nèi)容,這個(gè)方法中會(huì)判斷目標(biāo)進(jìn)程是否存在,存在則通知進(jìn)程啟動(dòng) Activity,否則就先將進(jìn)程創(chuàng)建出來
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
...
if (app != null && app.thread != null) {
...
// 如果進(jìn)程已存在,則通知進(jìn)程啟動(dòng)組件
realStartActivityLocked(r, app, andResume, checkConfig);
return;
...
}
// 否則先將進(jìn)程創(chuàng)建出來
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
...
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
...
}
5. ActivityManagerService.realStartActivityLocked 創(chuàng)建新 Activity
我們先來看 realStartActivityLocked 這個(gè)方法,這個(gè)方法會(huì)通過 ApplicationThread 回調(diào) UI 進(jìn)程創(chuàng)建一個(gè) Activity 出來,app.thread 就是我們之前傳遞過去的 ApplicationThread AIDL 反向回調(diào)
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//...code
app.thread.scheduleLaunchActivity(new Intent (r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global and
// override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
//...code
}
大家記住 realStartActivityLocked 這個(gè)方法,因?yàn)橐粫?huì)我們還會(huì)提到他,記住是這個(gè)方法讓我們開始創(chuàng)建 Activity 對象
6. Process.start 創(chuàng)建目標(biāo)進(jìn)程
在 4 中,我們看到 ActivityManagerService 會(huì)判斷目標(biāo)進(jìn)程存不存在,不存在就 fork 一個(gè)新的進(jìn)程出來,Process.start 就是創(chuàng)建進(jìn)程的代碼
系統(tǒng)在 fork 一個(gè)新的進(jìn)程后,會(huì)在新的進(jìn)程里面啟動(dòng) Ui 線程,也就是 ActivtyThread 對象,而 ActivtyThread.main() 方法才是一個(gè) app 進(jìn)程真正的開始‘
public static void main(String[] args){
...
Looper.prepareMainLooper();
//初始化Looper
...
ActivityThread thread = new ActivityThread();
//實(shí)例化一個(gè)ActivityThread
thread.attach(false);
//這個(gè)方法最后就是為了發(fā)送出創(chuàng)建Application的消息
...
Looper.loop();
//主線程進(jìn)入無限循環(huán)狀態(tài),等待接收消息
}
mian 方法中,先把 UI 線程的 looper 消息隊(duì)列準(zhǔn)備好,然后 new 一個(gè) UI 線程對象,然后初始化 UI 線程的參數(shù),最后把 UI 線程的 looper 消息隊(duì)列跑起來,UI 線程進(jìn)入等待任務(wù)階段
這里面我們需要詳細(xì)看看 thread.attach(false) UI 線程初始化參數(shù)方法干了什么
public void attach(boolean system){
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
//獲得IActivityManager實(shí)例,下面會(huì)看看它是個(gè)啥
try {
mgr.attachApplication(mAppThread);
//看見沒?關(guān)鍵啊。mAppThread這個(gè)參數(shù)下面也會(huì)說一下
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
恩,可以看到我們把 AIDL 反向回調(diào)通訊注冊到了 ActivityManagerService 里面,然后那必然操作又切回到了系統(tǒng)的 ActivityManagerService 進(jìn)程里,接著 ActivityManagerService 里面的代碼走到了 attachApplicationLocked 這個(gè)位置
attachApplicationLocked 方法很重要,期中執(zhí)行了2個(gè)操作,先創(chuàng)建 application 對象,再創(chuàng)建 Activity 對象,這2個(gè)方法可是串行執(zhí)行的,都是 AIDL 遠(yuǎn)程操作
//
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
....
// 創(chuàng)建 application 對象
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
...
// 然后再創(chuàng)建 Activity 對象
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
...
}
}
...
}
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
...
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
...
}
...
}
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,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
7. UI 線程接受消息,new application 對象
可以看見 attachApplicationLocked 又通過 ApplicationThread 回調(diào),讓 UI 進(jìn)程干活了,注意這個(gè) ApplicationThread 所在的進(jìn)程就不是我們發(fā)起 startActivity 的 LaunchActivity 所在的進(jìn)程了,而是我們剛剛 fork 出來的目標(biāo)進(jìn)程了
接著我們來看看 UI 進(jìn)程的 bindApplication 方法
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) {
...
sendMessage(H.BIND_APPLICATION, data);
}
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
ApplicationThread 發(fā)送了一個(gè) H.BIND_APPLICATION 的消息,該消息會(huì)由 ActivityThread 一個(gè)名叫 H 的 handle內(nèi)部類接收
//
public void handleMessage(Message msg) {
...
switch (msg.what) {
...
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;
...
}
}
private void handleBindApplication(AppBindData data) {
...
final InstrumentationInfo ii;
...
// 創(chuàng)建 mInstrumentation 實(shí)例
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
...
}
...
} else {
mInstrumentation = new Instrumentation();
}
...
Application app;
...
// 創(chuàng)建 Application 實(shí)例
try {
...
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
} finally {
...
}
...
}
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {// 傳入為 null 所以不走
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
...
return app;
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
該 handle 會(huì)創(chuàng)建一個(gè) mInstrumentation 實(shí)例,然后創(chuàng)建出上下文對象,application 對象,application 綁定上下文,mInstrumentation 對象會(huì)執(zhí)行 application.onCreate() 初始化
8. UI 線程接受消息,new activity 對象
在6里面,ActivityManagerService.attachApplicationLocked() 里面連著干了2件事,先創(chuàng)建 application ,完事再創(chuàng)建 activity 對象,在7里面我們創(chuàng)建完了 application 對象,下面就該創(chuàng)建 activity 對象了
到這 app 冷啟動(dòng)有和 activity 啟動(dòng) activity 走到一起了,之后2者也沒分別了,差別就是 app 冷啟動(dòng)多了創(chuàng)建 application 對象的過程,完事都一樣了,就是 創(chuàng)建 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) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
ApplicationThread.scheduleLaunchActivity() 方法里發(fā)送一個(gè) H.LAUNCH_ACTIVITY 創(chuàng)建 activity 對象的消息
然后 ActivityThread 的 handle 接受消息,由 Instrumentation new activity 對象,activity 對象初始化參數(shù),最后由 Instrumentation 執(zhí)行 activity.onCreate() 初始化方法
//
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) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public void handleMessage(Message msg) {
...
switch (msg.what) {
...
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
// 返回之前創(chuàng)建過的 application 對象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
...
// attach 到 window 上
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);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
} catch (Exception e) {
...
}
return activity;
}
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
public Activity newActivity(Class<?> clazz, Context context,
IBinder token, Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance) throws InstantiationException,
IllegalAccessException {
Activity activity = (Activity)clazz.newInstance();
ActivityThread aThread = null;
activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
info, title, parent, id,
(Activity.NonConfigurationInstances)lastNonConfigurationInstance,
new Configuration(), null /* referrer */, null /* voiceInteractor */,
null /* window */, null /* activityConfigCallback */);
return activity;
}
到這 activity 的創(chuàng)建流程算是完事了,之后走 activity 的生命周期函數(shù),再由 window 渲染界面顯示,但是這里我們還要看看 activity.attach方法,看看 activity 初始化了什么參數(shù),方面之后我們繼續(xù)說 window
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
mWindow = new PhoneWindow (this, window);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
if (voiceInteractor != null) {
if (lastNonConfigurationInstances != null) {
mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
} else {
mVoiceInteractor = new VoiceInteractor (voiceInteractor, this, this,
Looper.myLooper());
}
}
mWindow.setWindowManager(
(WindowManager) context . getSystemService (Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo . FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
創(chuàng)建了 PhoneWindow 窗口,給窗口對象注冊監(jiān)聽,通過窗口Window創(chuàng)建,初始參數(shù)賦值,把和 WindowManagerService 遠(yuǎn)程通訊的 WindowManagerImpl AIDL 對象綁定給 PhoneWindow