App應(yīng)用窗口由Activity加載,整個(gè)窗口創(chuàng)建和Activity啟動(dòng)關(guān)聯(lián)在一起。
如圖所示
從Activity啟動(dòng)說起
Activity啟動(dòng)方法在ActivityThread的performLaunchActivity方法中,保留主要方法調(diào)用
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
............
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//通過classloader 加載Activity類
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);
}
}
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 (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
//構(gòu)建activity內(nèi)部環(huán)境
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//調(diào)用onCreate方法,里面調(diào)用setContentView
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......................
return activity;
}
mInstrumentation.newActivity(..),通過ClassLoader實(shí)現(xiàn)Activity的實(shí)例化;
執(zhí)行activity.attach(..)方法,里面構(gòu)建activity實(shí)例所需要的內(nèi)部變量,包括創(chuàng)建Window和設(shè)置WindowManger
Window(PhoneWindow)和WindowManger創(chuàng)建
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) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
//創(chuàng)建PhoneWindow,用于視圖加載
mWindow = new PhoneWindow(this);
//將window事件通過回調(diào)接口,傳遞到Activity來處理
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
//設(shè)置WindowManger
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;
}
attach(..)方法中,通過實(shí)例化創(chuàng)建PhoneWindow實(shí)例,通過context.getSystemService()方法獲取WindowManager,
DecorView 創(chuàng)建
到現(xiàn)在Window和WindowmWindowManger已經(jīng)創(chuàng)建好了,Window創(chuàng)建好,需要添加視圖View,所有視圖的根視圖是DecorView,DecorView的創(chuàng)建在 setContent方法中。
上面說到創(chuàng)建Activity實(shí)例,調(diào)用attch方法,接下來就是調(diào)用mInstrumentation.callActivityOnCreate(..)方法,后面會(huì)調(diào)用Activity.onCreate()方法,在onCreate()方法中,通過setContentView()方法設(shè)置整個(gè)APP視圖。
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
setContent最終調(diào)用的是PhoneWindow的setContentView方法,
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
................
}
installDecor()方法調(diào)用generateDecor()方法來創(chuàng)建DecorView,DecorView是所有布局的根布局。
WindowManger何時(shí)會(huì)將Window添加進(jìn)來,閱讀后面代碼會(huì)發(fā)現(xiàn)當(dāng)Activity執(zhí)行OnResume時(shí)添加,添加時(shí)還會(huì)創(chuàng)建一個(gè)ViewRootImpl實(shí)例
ViewRootImpl創(chuàng)建
當(dāng)ActivityThread執(zhí)行handleResumeActivity方法時(shí),里面會(huì)執(zhí)行r.activity.makeVisible()方法
void makeVisible() {
if (!mWindowAdded) {
//將DecorView添加到WindowManager
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
addView在WindowManagerImpl實(shí)現(xiàn)中調(diào)用WindowManagerGlobal的addView方法
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
//ViewRootImpl 創(chuàng)建
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) {
// BadTokenException or InvalidDisplayException, clean up.
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
}
throw e;
}
}
到此DecorView展示出來,顯示在屏幕中,wm.addView(...)創(chuàng)建了ViewRootImpl,ViewRootImpl負(fù)責(zé)繪制各個(gè)子view
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
.........
requestLayout();
.................
//通過IPC,添加window交給WindowMangerServer
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
.........
}
}
mWindowSession類型是IWindowSession,是一個(gè)Binder對(duì)象,實(shí)現(xiàn)類是Seession,addToDisplay方法通過IPC調(diào)用WindowManagerService的addWindow(...)方法來添加Window;
requestLayout()方法調(diào)用scheduleTraversals()方法,后面異步方法刷新請(qǐng)求
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
在TraversalRunnable的run方法里面調(diào)用doTraversal()方法,doTraversal()方法會(huì)執(zhí)行performTraversals()方法,后面就是view的三個(gè)流程
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
if (mProfile) {
Debug.startMethodTracing("ViewAncestor");
}
performTraversals();
if (mProfile) {
Debug.stopMethodTracing();
mProfile = false;
}
}
}
ViewRootImpl除了繪制view,還包括分發(fā)底層傳遞的行為事件。如通過WindowInputEventReceiver獲取傳遞過來的點(diǎn)擊事件,通過handler轉(zhuǎn)發(fā)一直傳遞到Activity,大致流程:
硬件 --> ViewRootImpl --> DecorView --> PhoneWindow --> Activity
Activity不負(fù)責(zé)視圖控制,一個(gè)Activity包含一個(gè)Window,Windo表示一個(gè)窗口
WIndow是視圖承載器,內(nèi)部持有DecorView,DecorView是view的根布局;Window是抽象類,真正持有DecorView是PhoneWindow。Window通過WindowManger將DecorView添加進(jìn)來,將DecorView交給ViewRoot進(jìn)行繪制和其他交互操作。
DecorView是Fragment子類,為Android視圖樹的根節(jié)點(diǎn)。
ViewRootImpl通過IWindow連接WindowmangerService和DecorView。View繪制流程也是ViewRoot完成。ViewRoot不屬于View樹一部分,可以接收事件分發(fā),以及界面刷新等
Activity類似控制器,不負(fù)責(zé)視圖部分。Window是承載器,裝在視圖;DecorView是頂層視圖,ViewRootImpl連接器,負(fù)責(zé)事件傳遞和用戶交互。