一些基本概念
Window
- 定义:Window是一个抽象概念,代表一个窗口,它负责界面的展示以及交互。在Android中,Window的具体实现类是PhoneWindow。
- 功能:Window内部持有一个DecorView作为视图的根布局,并通过WindowManager将DecorView加载到窗口中。它还负责处理与窗口相关的各种事件,如窗口大小变化、焦点变化等。
Activity
- 定义:Activity是Android四大组件之一,负责界面展示、用户交互与业务逻辑处理。
- 功能:Activity内部维护着一个Window对象,通过该Window对象来管理视图的添加、布局、绘制等工作。Activity通过调用setContentView()方法将布局资源添加到Window的内容视图中。此外,Activity还负责处理生命周期事件,如创建、暂停、恢复和销毁等。
View
- 定义:View是Android用户界面基本构建块之一,是各种UI组件的基类。
- 功能:View负责显示应用程序中的内容和与用户进行交互。它通常被放置在Window容器中,由Window进行管理和展示。View具有自己的属性、样式和行为,并可以包含其他View或ViewGroup来构建复杂的用户界面。
WindowManager
- 定义:WindowManager是一个接口,用于管理窗口的添加、删除和更新等操作。
- 功能:WindowManager的具体实现类是WindowManagerImpl,它内部将所有的方法调用转交给WindowManagerGlobal来处理。WindowManagerGlobal通过调用ViewRootImpl来完成对View的操作。WindowManager还负责处理与窗口相关的各种事件,如窗口大小变化、焦点变化等,并将这些事件传递给相应的Window进行处理。
ViewRootImpl
- 定义:ViewRootImpl是视图层次结构的顶部,它实现了View与WindowManager之间所需要的协议。
- 功能:ViewRootImpl负责将View和布局参数添加到屏幕上,并控制View的测量、布局和绘制过程。它还负责处理与View相关的事件,如触摸事件、按键事件等,并将这些事件传递给相应的View进行处理。此外,ViewRootImpl还通过IWindowSession接口与WindowManagerService进行通信,以实现对窗口的管理和更新。
关系总结
- Window与Activity:Activity内部持有一个Window对象,通过该Window对象来管理视图和界面展示。Window作为Activity的下属或视图的管理者,负责处理与窗口相关的各种事件。
- Window与View:Window是视图的承载器,内部持有一个DecorView作为视图的根布局。View被放置在Window容器中,由Window进行管理和展示。
- Activity与View:Activity通过setContentView()方法将布局资源(由View和ViewGroup组成)添加到Window的内容视图中。用户与Android应用的交互主要是通过View进行的,这些事件会被View捕获并传递给Activity进行处理。
- WindowManager与Window/View:WindowManager负责管理窗口的添加、删除和更新等操作。它通过WindowManagerImpl和WindowManagerGlobal来实现对Window和View的管理。WindowManager还负责处理与窗口相关的各种事件,并将这些事件传递给相应的Window进行处理。
- ViewRootImpl与Window/View:ViewRootImpl是视图层次结构的顶部,它实现了View与WindowManager之间所需要的协议。它负责将View和布局参数添加到屏幕上,并控制View的测量、布局和绘制过程。ViewRootImpl还与WindowManagerService进行通信,以实现对窗口的管理和更新。
View Three的创建过程
流程
列子:用户启动一个界面。
- 经过一系列后AMS会通知应用启动一个Activity的,最终将到ActivityThread所管理的LAUNCH_ACTIVITY消息,执行handleLaunchActivity()。
- 创建Activity对象和Window对象。
- 创建DecorView,加载页面内容布局到DecorView上,形成View树。
- 需要将View添加到本地的WindowManagerGlobal中,最终注册到WMS中。
源码(以下源码分析基于7.1和8.0)
handleLaunchActivity
/*frameworks/base/core/java/android/app/ActivityThread.java*/
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);//启动Activity
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed,r.lastProcessedSeq, reason);//resume当前Activity
}
}
- performLaunchActivity()生成一个Activity对象,且执行Activity的attach(),通过callActivityOnCreate()间接调用Activity.onCreate()。Activity的attach()主要是对内部一些变量赋值,如mWindow。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);//加载创建这个Activity
...
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplication(false,mInstrumentation);
...
if (activity != 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);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
...
} catch (Exception e) {
...
}
}
- Activity.onCreate()里会执行setContentView()生成DecorView,setContentView()最终是调用到Window.java的实现类PhoneWindow。
/*frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java*/
public void setContentView(int layoutResID) {
if (mContentParent == null) {
//首次加载这个函数的情况
installDecor();//先生成mDecor
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();//否则移除旧的view
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
...
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);//根据资源ID创建View,
}
...
}
private void installDecor() {
mForceDecorInstall = false;
if (mDecor == null) {
//创建一个DecorView
mDecor = generateDecor(-1);
...
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
}
}
- 取出Window样式。
- 根据layoutResource指定的layout(即xml)文件,来inflate出对应的View,将View添加到DecorView中。
- DecorView包含两部分内容,一个是通过setContentView实际要显示的视图,另外一个是系统的视图如Title,ActionBar等。
protected ViewGroup generateLayout(DecorView decor) {
TypedArray a = getWindowStyle();//获取窗口样式
//根据具体的样式为layoutResource设置匹配的资源
int layoutResource;
int features = getLocalFeatures();
// System.out.println("Features: 0x" + Integer.toHexString(features));
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
layoutResource = R.layout.screen_swipe_dismiss;
setCloseOnSwipeEnabled(true);
} else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
}
...
final View root = inflater.inflate(layoutResource, null);
mDecor.addView(root,new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
ViewGro