- Android Framework 之 Window / Win
- Android Framework 之 Window / Win
- Android Framework 之 Window / Win
- Android Framework 之 Window / Win
- Android Framework 之 Window / Win
- Android Framework 之 Window / Win
- Android Framework 之 Window / Win
- Android Window / WindowManager 小
- 日更挑战-Android Window、Activity、Dec
- Android UI-测量-布局-绘制-机制
View 是依附在 Window 上,是不能单独存在的。
因此,需要了解各种View(广义上的) 如 Activity / Dialog /Toast 等,创建各自Window的过程.
这里介绍 Activity 的 Window 的创建过程.
1. Activity 的创建
在 ActivityThread 中创建 Activity
//ActivityThread.java
package android.app;
public final class ActivityThread extends ... {
/** Core implementation of activity launch. */
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); //(1)
...
if (activity != null) {
activity.attach(appContext, this,...); //(2)
}
分析:
(1) 在 performLaunchActivity 中, 通过 类加载器 创建 activity
(2) 然后调用 activity.attach(),这里将会 创建Window
2. 创建 Window
//Activity.java
package android.app;
@UiContext
public class Activity extends ContextThemeWrapper..{
final void attach(Context context, ActivityThread aThread,...) {
mWindow = new PhoneWindow(this, window, activityConfigCallback);//(1)
mWindow.setWindowControllerCallback(mWindowControllerCallback);//(2)
mWindow.setCallback(this);
mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),..);//(4)
mWindowManager = mWindow.getWindowManager();//(4)
}
public Window getWindow() {//(3)
return mWindow;
}
public WindowManager getWindowManager() {//(4)
return mWindowManager;
}
分析:
(1) 在 attach 方法中, 创建了 PhoneWindow 对象
(2) 设置了callback,即后续 Window 的 回调可以 通知到 该 activity 对象.
(3) 提供了 getWindow() 接口获取 Window 对象.
(4) 获取 WindowManager 并设置给 Window 对象,然后再通过 Window接口获取,Activity 也提供接口.
2. 设置视图内容 setContentView
Activity.attach() 会创建 Window, 还需要把 布局内容 添加 DecorView中.
最终也会调用 Window 的 setContentView.
//Activity.java
package android.app;
public class Activity extends ContextThemeWrapper..{
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
...
}
显然,还是要看 PhoneWindow 的实现.
package com.android.internal.policy;
public class PhoneWindow extends Window ... {
private DecorView mDecor;
ViewGroup mContentParent;
@Override
public void setContentView(int layoutResID) { //(1)
if (mContentParent == null) { //(2)
installDecor();//(2)
} ...
...
mLayoutInflater.inflate(layoutResID, mContentParent);//(5)
}
private void installDecor() {
if (mDecor == null) { //(3)-1
mDecor = generateDecor(-1); //(3)-2
...
} else {
mDecor.setWindow(this);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
}
protected DecorView generateDecor(int featureId) {
....
return new DecorView(context, featureId, this, getAttributes());//(3)-3
}
}
分析:
(1) setContentView 的参数为 layoutResID, 即布局文件的id
(2) 判断 mContentParent 是否为空,如果是,则会调用 installDecor.
(3) installDecor 又会判断 mDecor 是否为空,如果是则调用 generateDecor 创建DecorView对象
(4) mContentParent 为空,则会调用 generateLayout 创建, 传入的参数为 非空的 DecorView 对象.
(5) 将布局资源即layoutResID指定的文件 , 添加到 mContentParent 即 父ViewGroup
3. 将 DecorView 添加到 Window 中.
经过上面的1和, DecorView 已创建, 并且 布局资源 也添加 到了 mContentParent.
但是, 此时 DecorView 还没被 WindowManager 添加到 Window 中.
先要在 ActivityThread 的 handleResumeActivity 中,调用 activity.onResume.
接着在 将 DecorView 添加到 Window 中.
//ActivityThread.java
package android.app;
public final class ActivityThread extends ... {
@Override
public void handleResumeActivity(ActivityClientRecord r ..) {//(1)
...
if (!performResumeActivity(r, finalStateRequest, reason)) { //(2)
return;
}
...
final Activity a = r.activity; //(3)
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow(); // (4)
View decor = r.window.getDecorView(); // (5)
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager(); //(6)
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;//(7)
..
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l); //(8)
}..
}
}
分析:
(1) handleResumeActivity 里的参数 r 是 ActivityClientRecord 对象, 包含 activity 的信息
(2) 主要执行 回调函数 activity.onResume
(3) 获取当前 activity 实例对象
(4) 将 activity 的 Window 赋值给 r.window
(5) 通过 activity 的 window 获取到 decorView
(6) 通过 activity 获取 ViewManager (即WindowManager )对象,
从2-(4) 的分析,可以知道,其实是通过 mWindow.getWindowManager 获取的.
(7) 更新 activity 的 mDecor
(8) 真正 调用 WindowManager 添加 DecorView. 这里就回到之前讲过的知识上了.
-- End --







网友评论