android主动显示流程,Activity加载显示基本流程
本文章是基于Android源碼6.0講解Activity加載顯示基本流程
首先上一張圖給大家一個直觀的了解
首先一個布局頁面的加載是在Activity中的setContentView(R.layout.res)開始;
我們就從Acitvity源碼中的setContentView方法入手
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
通過源碼我們可以看到layoutResID又傳給了getWindow()中的setContentView(layoutResID)方法;
mWindow = new PhoneWindow(this);
public Window getWindow() {
return mWindow;
}
getWindow()返回的是PhoneWindow的對象
我們來看PhoneWindow中setContentView(layoutResID)方法
PhoneWindow是一個隱藏類,在源碼sources/andorid-23/com/android/internal/policy中
PhoneWindow中setContentView方法
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();//Activity新創(chuàng)建時mContentParent 為空,調用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);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
我們來看PhoneWindow中installDecor()方法中的關鍵部分
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor(); //@1
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor); //@2
...
}
mLayoutInflater.inflate(layoutResID, mContentParent);//@3
}
在PhoneWindow源碼中聲明了 private DecorView mDecor;
DecorView 是PhoneWindow中的一個內部類繼承了FrameLayout,是一個幀布局
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
...
}
@1 首先調用mDecor = generateDecor();返回的是一個 DecorView的對象,這就是所有頁面的跟布局
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
@2 其次調用mContentParent = generateLayout(mDecor);
protected ViewGroup generateLayout(DecorView decor) {
...
} else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
layoutResource = R.layout.screen_simple_overlay_action_mode;
} else {
// Embedded, so no decoration is needed.
layoutResource = R.layout.screen_simple;
// System.out.println("Simple!");
}
View in = mLayoutInflater.inflate(layoutResource, null);
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
mContentRoot = (ViewGroup) in;
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
...
return contentParent;
}
這里的layoutResource是源碼中的布局,我們來看一下R.layout.screen_simple
在sdk/platforms/android-23/data/res/layout路徑中
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
android:inflatedId="@+id/action_mode_bar"
android:layout="@layout/action_mode_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarTheme" />
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundInsidePadding="false"
android:foregroundGravity="fill_horizontal|top"
android:foreground="?android:attr/windowContentOverlay" />
R.layout.screen_simple就是一個簡單的線性布局,通過mLayoutInflater.inflate和decor.addView添加到DecorView中,
再通過ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);把R.layout.screen_simple中id
為id/content的Framelayout賦值給contentParent
@3 最后通過mLayoutInflater.inflate(layoutResID, mContentParent);把我們寫的布局添加到mContentParent中。
未完待續(xù)...
總結
以上是生活随笔為你收集整理的android主动显示流程,Activity加载显示基本流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 流量节省模式 Android,这三种方法
- 下一篇: 0.20风阻系数史上最低!奔驰全新车型预