[Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法
博客首页:http://www.cnblogs.com/kezhuang/p/
关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下
《[Android FrameWork 6.0源码学习] Window窗口类分析》
本章博客是接着上边那篇博客分析,目的是为了引出分析ViewRootImpl这个类。现在只是分析完了Window和ActivityThread的调用过程
从ActivityThread到WindowManager再到ViewRootImpl这块还属于空白部分,所以要补这篇博客
在上篇博客的末尾提到最后是由WindowManager的addView来请求显示界面,那么我们接着分析
WindowManager这是一个接口,他继承了ViewManager这个接口,所以具有管理View的能力
WindowManager这个实例是通过 Activity.getWindowManager 方法获取的,我们先找到他的实例,在逐渐去看addView函数
public WindowManager getWindowManager() {
return mWindowManager;
}
Activity中是这样定义的该函数,返回了mWindowManager对像,接下来找一下赋值mWindowManager对象的地方
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) {
mWindow = new PhoneWindow(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
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();
}
我们看到在Activity初始化时候调用的attach方法中赋值了mWindowManager方法,但是这个值是从mWindow对象中获取到的,我们进入看一下
public WindowManager getWindowManager() {
return mWindowManager;
}
在Window中也是这样定义的,返回mWindowManager
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);
}
Window中的mWindowManager是在setWindowManager中创建而来,而这个setWindowManager其实是在Activity的attach方法中调用
可以看到其实就是用的系统服务WindowManager强转成WindowManagerImpl之后又调用了createLocalWindowManager方法得到的对象
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
这个方法也很简单,就是new了一下WindowManagerImpl
OK了,到现在可以知道WindowManager的实现类为WindowManagerImpl,那么我们继续分析它实现的addView方法
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
该方法定义在WindowManagerImpl中,mGlobal为WindowManagerGlobal对象,是一个系统单例对象
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
if (display == null) {
throw new IllegalArgumentException("display must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
parentWindow.adjustLayoutParamsForSubWindow(wparams);
} else {
// If there's no parent, then hardware acceleration for this view is
// set from the application's hardware acceleration setting.
final Context context = view.getContext();
if (context != null
&& (context.getApplicationInfo().flags
& ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// Start watching for system property changes.
if (mSystemPropertyUpdater == null) {
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
mRoots.get(i).loadSystemProperties();
}
}
}
};
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
}
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {
// Don't wait for MSG_DIE to make it's way through root's queue.
mRoots.get(index).doDie();
} else {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
// The previous removeView() had not completed executing. Now it has.
}
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
//创建了一个新的ViewRootImpl对象出来
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
//为当前界面保存ViewRootImpl和view还有添加的Layout参数
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
//调用ViewRootImpl中的setView方法,准备进行View的重绘流程,并且绘制到界面上
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;
}
}
这篇博客到这就结束了,接下来我总结下上边的流程
1.Activity初始化的时候创建了一个WindowManager对象(和系统的WindowManager服务还有点区别)
2.利用这个Activity专属的WindowManager对象请求添加一个View到当前界面上
3.WindowManager找到自己的实现类WindowManagerImpl,然后在委托给系统单例类WindowManagerGlobal处理
4.WindowManagerGlobal会创建一个ViewRootImpl对象出来
5.ViewRootImpl对象调用setView方法,然后进行界面重绘最后交给Surface进行界面展示
Ok了,很清晰的分析出了从WindowManager到ViewRootImpl的过程,接下来就可以分析ViewRootImpl.setView和ViewRootImpl的performTraversals方法了
[Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法的更多相关文章
- [Android FrameWork 6.0源码学习] View的重绘过程之Draw
View绘制的三部曲,测量,布局,绘画现在我们分析绘画部分测量和布局 在前两篇文章中已经分析过了.不了解的可以去我的博客里找一下 下面进入正题,开始分析调用以及函数原理 private void pe ...
- [Android FrameWork 6.0源码学习] View的重绘过程之Layout
View绘制的三部曲,测量,布局,绘画现在我们分析布局部分测量部分在上篇文章中已经分析过了.不了解的可以去我的博客里找一下 View的布局和测量一样,都是从ViewRootImpl中发起,ViewRo ...
- [Android FrameWork 6.0源码学习] View的重绘过程
View绘制的三部曲, 测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...
- [Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法
博客首页:http://www.cnblogs.com/kezhuang/p/ 本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作 /i* ...
- Android View的重绘过程之WindowManager的addView方法
博客首页:http://www.cnblogs.com/kezhuang/p/ 关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下 <[An ...
- [Android FrameWork 6.0源码学习] LayoutInflater 类分析
LayoutInflater是用来解析XML布局文件,然后生成对象的ViewTree的工具类.是这个工具类的存在,才能让我们写起Layout来那么省劲. 我们接下来进去刨析,看看里边的奥秘 //调用i ...
- [Android FrameWork 6.0源码学习] ViewGroup的addView函数分析
Android中整个的View的组装是采用组合模式. ViewGroup就相当与树根,各种Layout就相当于枝干,各种子View,就相当于树叶. 至于View类.我们就当它是个种子吧.哈哈! Vie ...
- [Android FrameWork 6.0源码学习] Window窗口类分析
了解这一章节,需要先了解LayoutInflater这个工具类,我以前分析过:http://www.cnblogs.com/kezhuang/p/6978783.html Window是Activit ...
- 【Spark2.0源码学习】-1.概述
Spark作为当前主流的分布式计算框架,其高效性.通用性.易用性使其得到广泛的关注,本系列博客不会介绍其原理.安装与使用相关知识,将会从源码角度进行深度分析,理解其背后的设计精髓,以便后续 ...
随机推荐
- Win10下用Anaconda安装TensorFlow
什么是Anaconda anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项.它是一个用python开发机器学习的必备工具. 什么是ten ...
- 漫谈PID——实现与调参
闲话: 作为一个控制专业的学生,说起PID,真是让我又爱又恨.甚至有时候会觉得我可能这辈子都学不会pid了,但是经过一段时间的反复琢磨,pid也不是很复杂.所以在看懂pid的基础上,写下这篇文章,方便 ...
- C#封装程序集属性方法注释说明
一.使用封装程序集好处: 在很多分布式应用程序开发中,针对每一种功能可能条用的接口不一样,往往习惯将需要被调用的接口,封装成DLL给调用方应用后使用,这样既规范了调用的方式,又避免了调用出现参数请求方 ...
- spring之事务
1.编程式事务 2.声明式事务:aop
- Activity 与 springMvc相整合
准备环境: springMvc框架及Activity所需要的jar: 创建spring-activity.xml文件,里面内容: <?xml version="1.0" en ...
- 筛法求素数Java
输出:一个集合S,表示1~n以内所有的素数 import java.util.Scanner; public class 筛法求素数 { public static void main(String[ ...
- VMware Workstation 学习笔记
1. 什么是虚拟机:虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的.可以运行在一个完全隔离环境中的完整计算机系统. 2. 虚拟机的用途:测试软件.搭建某种特定需求的环境 ...
- iOS 提交审核报错 ERROR ITMS-90087解决办法
ERROR ITMS-: "Unsupported Architectures. The executable for yht.temp_caseinsensitive_rename.app ...
- 5分钟spark streaming实践之 与kafka联姻
你:kafka是什么? 我:嗯,这个嘛..看官网. Apache Kafka® is a distributed streaming platform Kafka is generally used ...
- Linux最佳的云存储服务分析
什么样的云服务才适合作为 Linux 下的存储服务?兄弟连www.itxdl.cn来帮大家分析一下! 大量的免费空间.毕竟,个人用户无法支付每月的巨额款项. 原生的 Linux 客户端.以便你能够方便 ...