版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:http://www.lxweimin.com/p/76f94c6452c0
先拋幾個問題
1:什么是Activity,它的作用是什么,我們一個android app看到的界面真的是Activity嗎,如果不是,那是什么。
2:我們經常看到的Context,到處都是Context,服務都是通過它獲取的,它和Activity是什么關系。
3:看到的一些文章和帖子總是會說一個Activity會對應一個PhoneWindow,那什么又是PhoneWindow,Activity和PhoneWindow的關系又是什么。
4:我們在自定義的Activity,比如MainActivity的setContentView中設置了xml,最后就是我們看到的視圖,那么它和PhoneWindow和Activity又有什么關系。
5:有View和ViewGroup我們可以理解,但是有時候又會看到一個ViewRootImpl和DecorView。它們又是什么關系,和Activity又是什么關系。
6:Activity,Context,Application,DecorView,PhoneWindow,ActivityThread,以及ActivityManagerService,WindowsManagerService它們是如何構建一個簡單的helloworld android應用的。Application和Activity是誰先創建的,android應用中為什么我們又不用繼承Application寫一個MyApplication類。而如果寫了,它又有什么用。
先說一個場景,當我們點擊手機桌面第一次運行app的時候,Activity是如何啟動的。這個過程要說清楚其實還是比較復雜的,本篇中我們先跳躍式的從main函數開始運行說起。main函數在ActivityThread類中,如下:
創建Activity或者說創建View
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
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);
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");
}
main函數中創建了Looper(關于Looper和Handler和Message在后續講)和ActivityThread,并且調用attach函數和ActivityManagerService關聯起來,為什么需要和ActivityManagerService關聯,因為我們知道Activity何時創建,管理都是ActivityManagerService管理的,所以就需要告訴ActivityManagerService我現在已經運行了main函數,以后有什么需要任務你就需要告訴我,而ActivityManagerService是怎么和應用通信呢,這就需要注意到attach中的這段代碼
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mgr.attachApplication(mAppThread),mgr是ActivityManagerService的client代理mAppThread是一個Binder對象。
final ApplicationThread mAppThread = new ApplicationThread();
private class ApplicationThread extends ApplicationThreadNative {
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
@Override
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();
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
}
現在我們知道了,ActivityManagerService持有應用的mAppThread對象,通過mAppThread服務端可以告應用進行啟動Activity和其它的一些操作,比方說調用scheduleLaunchActivity啟動Activity。ActivityThread中有一個H類,它繼承Handler,ActivityManagerService調用應用的操作最終通過H類發送消息,從Binder線程轉換到應用進程的主線程進程完成。
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
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;
}
handleLaunchActivity中有一個performLaunchActivity調用,它會創建Activity(也就是new一個Activity),我們常常在Activity的onCreate函數中做一些初始化操作,到時我們好像很少寫Activity的構造函數,比如我們的MainActivity,我們其實也是可以寫它的構造函數,并且可也在里面完成一些操作,只是很少這樣做罷了。至此我們終于知道了Activity的創建了。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// 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();
Activity a = performLaunchActivity(r, customIntent);
}
performLaunchActivity比較長,我們截取部分關鍵代碼分析。part1:通過mInstrumentation的newActivity調用new出來我們的Activity,part2:創建了Activity之后會創建應用的運行Application上下文,然后調用關鍵的attach函數
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//part1,通過mInstrumentation的newActivity調用new出來我們的Activity
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) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
//part2,創建了Activity之后會創建應用的運行Application上下文,然后調用關鍵的attach函數
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = 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, window);
//part3,創建了Activity和attach之后,就調用到了我們熟悉的Activity的OnCreate
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
}
創建了Activity之后,在part2中會順帶著獲取到Application的對象,代表著我們應用的Application上下文,如果沒有,就會創建。packageInfo是一個LoadedApk對象
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
try {
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
}
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);//會調用Application的onCreate函數
} catch (Exception e) {
}
}
至此我們明白了Application的創建和它的onCreate函數的調用過程。回調part2中的Activity的attach函數中來,它有一個參數就是Application。
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);
.
.
}
終于看到PhoneWindow了,它就是在Activity的attach的時候創建出來的,這注意兩行關鍵代碼mWindow.setWindowControllerCallback(this)和mWindow.setCallback(this),因為Activity繼承了Window的Callback,所以可以將Activity作為PhoneWindow的回調設置進去,后面PhoneWindow接收到的消息和一些其它操作都是通過這個回調告訴Activity。
part3,創建了Activity和attach之后,就調用到了我們熟悉的Activity的OnCreate
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);//onCreate中比如MainActivity繼承Activity,就調用到了MainActivity的onCreate函數
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
至此終于見到我們熟悉的Activity的onCreate和setContentView(R.layout.activity_main)函數了。setContentView在Activity中如下
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
getWindow()返回的是mWindow,就是在上面attach中創建的PhoneWindow,那么PhoneWindow的setContentView又做了什么呢。我們xml布局的視圖又是如何了呢。
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
}
private void installDecor() {
mForceDecorInstall = false;
if (mDecor == null) {
mDecor = generateDecor(-1);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
}
}
protected DecorView generateDecor(int featureId) {
return new DecorView(context, featureId, this, getAttributes());
}
到這里我們終于見到DecorView了,DecorView它是什么東西呢,它是繼承FrameLayout的布局,也就是這里我們終于見到了View,現在也明白了Activity的頂布局是DecorView了,我們的xml布局中的View只是DecorView的Content布局內容。
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
但到目前為止我們僅僅只見到過Activity的創建和它OnCreate函數的運行,也知道了我們的xml視圖實例化之后加入到了DecorView中,這樣就顯示了視圖,如何接收onTouchEvent事件了嗎,當然不是。這才是一部分,或者稱之為View視圖已經準備好了,已經創建了,剩下就是如何顯示它們了。
顯示Activity或者說顯示View
回到開始的handleLaunchActivity,第一部分創建Activity或者說創建View也即運行完performLaunchActivity函數之后,來到了handleResumeActivity函數,如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}
}
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
return;
}
r = performResumeActivity(token, clearHide, reason);
if (r != null) {
final Activity a = r.activity;
.
.
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient && !a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
}
其中的performResumeActivity會最終運行到Activity的Resume函數。但是這個時候其實我們的View是沒有顯示的,那Activity都Resume了View還沒有顯示,那是什么時候顯示呢,往下看注意這段代碼wm.addView(decor, l);decor是上文中的DecorView對象,wm是什么呢,ViewManager wm = a.getWindowManager()
public WindowManager getWindowManager() {
return mWindowManager;
}
那mWindowManager是什么實例呢,它又是在什么地方創建或者賦值的,Activity的attach中有一行mWindowManager = mWindow.getWindowManager(),也就是說mWindowManager是獲取的PhoneWindow的對象。繼續往下跟Window類中有一個setWindowManager函數
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
mAppToken = appToken;
mAppName = appName;
mHardwareAccelerated = hardwareAccelerated
|| SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
if (wm == null) {
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
PhoneWindow繼承Window,注意attach中有一段
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
也就是說mWindowManager是我們的mContext.getSystemService(Context.WINDOW_SERVICE)獲取到的WINDOW_SERVICE調用的createLocalWindowManager創建的WindowManagerImpl對象
public final class WindowManagerImpl implements WindowManager {
//注意這個WindowManagerGlobal,它是一個單例對象,就是說一個進程只有一個實例
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow);
}
}
mContext為Context對象,Context是一個抽象類,它的實現類是ContextImpl,查看ContextImpl的getSystemService函數,最終調用到了SystemServiceRegistry的getSystemService,而getSystemService返回的是它的HashMap SYSTEM_SERVICE_FETCHERS中保存的注冊的服務,一下就是我們常用到的ActivityManager和WindowManager
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
final class SystemServiceRegistry {
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
private static int sServiceCacheSize;
// Not instantiable.
private SystemServiceRegistry() { }
static {
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
registerService(Context.WINDOW_SERVICE, WindowManager.class,
new CachedServiceFetcher<WindowManager>() {
@Override
public WindowManager createService(ContextImpl ctx) {
return new WindowManagerImpl(ctx);
}});
}
回到handleResumeActivity中的wm.addView(decor, l);,也就是調用到了WindowManagerImpl的addView
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
最終調用到了WindowManagerGlobal中的addView,它里面又做了什么呢
public final class WindowManagerGlobal {
private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
int index = findViewLocked(view, false);
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
}
}
}
這里我們終于見到了ViewRootImpl。但是,什么,做了這么多,就是看到new了一個ViewRootImpl對象,然后將View和new的ViewRootImpl對象分別add到mViews和mRoots列表中,說好的顯示View呢,怎么接收Event等呢。add就行了嗎?這個就要從ViewRootImpl的setView說起了,說說ViewRootImpl了。
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {
public ViewRootImpl(Context context, Display display) {
mContext = context;
//代表WindowManagerService的WindowSession
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplay = display;
mBasePackageName = context.getBasePackageName();
mThread = Thread.currentThread();
mWinFrame = new Rect();
//代表WindowManagerService和ViewRootImpl通信的mWindow,W對象
mWindow = new W(this);
mFirst = true; // true for the first time the view is added
mAdded = false;
//代表View和ViewRootImpl關聯的對象AttachInfo
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
mFallbackEventHandler = new PhoneFallbackEventHandler(context);
//我們常常說的編舞者對象Choreographer,控制UI刷新的,怎么做的1s內刷新60HZ的
mChoreographer = Choreographer.getInstance();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
loadSystemProperties();
}
}
ViewRootImpl的構造函數中的幾個關鍵對象都作了注釋 //代表WindowManagerService的WindowSession//代表WindowManagerService和ViewRootImpl通信的mWindow,W對象//代表View和ViewRootImpl關聯的對象AttachInfo//我們常常說的編舞者對象Choreographer,控制UI刷新的,怎么做的1s內刷新60HZ的。
上文說的要從ViewRootImpl的setView說起,setView怎么說呢,代碼比較長,截取關鍵部分
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
mAttachInfo.mDisplayState = mDisplay.getState();
mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
// If the application owns the surface, don't enable hardware acceleration
if (mSurfaceHolder == null) {
enableHardwareAcceleration(attrs);//硬件加速初始化部分
}
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
requestLayout();
if ((mWindowAttributes.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
mInputChannel = new InputChannel();
}
mForceDecorViewVisibility = (mWindowAttributes.privateFlags
& PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
//mWindowSession添加窗口顯示,一個應用只分配一個sWindowSession
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
} catch (RemoteException e) {
}
//mInputChannel,輸入通道,WindowInputEventReceiver,輸入事件接收相關代碼
if (mInputChannel != null) {
if (mInputQueueCallback != null) {
mInputQueue = new InputQueue();
mInputQueueCallback.onInputQueueCreated(mInputQueue);
}
mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
Looper.myLooper());
}
}
setView中的enableHardwareAcceleration(attrs)是關于硬件加速的,設計到View的
Draw問題,mWindowSession的addToDisplay是將視圖和窗口關聯的過程。mInputChannel輸入通道,WindowInputEventReceiver接收輸入事件,有了這些一個app的完整的顯示,UI更新,接收事件等終于準備好了,剩下的就是點擊屏幕,事件如何傳遞到Activity和View的問題,View如何將內容顯示出來,并且不斷的進行UI更新,這個就是Choreographer和Draw的問題,而怎么Draw就涉及到硬件加速Draw和softDraw,本篇就先到這,下篇再講。
這里我們總結下ActivityThread接收到ActivityManagerService通過Binder調用,創建Activity的過程,這些過程是平時做應用開發會有所涉及的。
1:ActivityThread的mAppThread成員變量調用scheduleLaunchActivity成員函數準備啟動Activity,發送LAUNCH_ACTIVITY轉換給ActivityThread的H類對象mH處理(轉換到主線程處理)。
2:mH對象接收到LAUNCH_ACTIVITY消息之后handleMessage調用handleRelaunchActivity成員函數,參數為ActivityClientRecord對象,表示記錄Activity的一些Client端信息,比如包名,組件名稱等等。
3:handleLaunchActivity函數中調用performLaunchActivity,執行啟動Activity。
3.1:performLaunchActivity函數調用mInstrumentation new出需要啟動的Activity,比如MainActivity
3.1.1:new出Activity之后,通過調用LoadedApk的makeApplication,創建應用的Application對象,同時創建Activity自己的Context
3.1.2:這一切準備好之后,調用Activity的attach函數。
3.1.2.1:attach中主要創建了PhoneWindow對象,作為Activity對應的Window對象。
3.1.3:Activity的attach運行完成之后通過mInstrumentation調用Activity的OnCreate,調用到我們熟悉的OnCreate函數
3.1.3.1:OnCreate·函數中,調用setContentView。這時會new出Activity窗口的根布局DecorView同時將我們自己的xml布局實例化成View,并添加到DecorView根布局中。
3.2:handleResumeActivity函數運行完成之后執行handleResumeActivity,在handleResumeActivity函數中將DecorView加入到WindowManager中,
在add DecorView的過程中創建了ViewRootImpl對象。ViewRootImpl對象完成UI Draw,消息接收等,細節后續篇章講解。
4:進入Looper消息循環,等等消息輸入