[Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法
博客首页:http://www.cnblogs.com/kezhuang/p/
本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作
/i** * We have one child */ public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { if (mView == null) { mView = view; //获取当前屏幕最新的状态,并且给当前DecorView注册屏幕监听,用来检测灭屏和亮屏 mAttachInfo.mDisplayState = mDisplay.getState(); mDisplayManager.registerDisplayListener(mDisplayListener, mHandler); mViewLayoutDirectionInitial = mView.getRawLayoutDirection(); mFallbackEventHandler.setView(view); mWindowAttributes.copyFrom(attrs); if (mWindowAttributes.packageName == null) { mWindowAttributes.packageName = mBasePackageName; } attrs = mWindowAttributes; // Keep track of the actual window flags supplied by the client. mClientWindowLayoutFlags = attrs.flags; //清除辅助功能的焦点 setAccessibilityFocus(null, null); if (view instanceof RootViewSurfaceTaker) { mSurfaceHolderCallback = ((RootViewSurfaceTaker)view).willYouTakeTheSurface(); if (mSurfaceHolderCallback != null) { mSurfaceHolder = new TakenSurfaceHolder(); mSurfaceHolder.setFormat(PixelFormat.UNKNOWN); } } // Compute surface insets required to draw at specified Z value. // TODO: Use real shadow insets for a constant max Z. if (!attrs.hasManualSurfaceInsets) { final int surfaceInset = (int) Math.ceil(view.getZ() * 2); attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset); } //获取屏幕兼容模式,一般情况下不考虑 mTranslator是空的 CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo(); mTranslator = compatibilityInfo.getTranslator(); //开启硬件加速功能 if (mSurfaceHolder == null) { enableHardwareAcceleration(attrs); } boolean restore = false; //Application不考虑兼容模式 if (mTranslator != null) { mSurface.setCompatibilityTranslator(mTranslator); restore = true; attrs.backup(); mTranslator.translateWindowLayout(attrs); } if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs); //Application不考虑兼容模式 if (!compatibilityInfo.supportsScreen()) { attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; mLastInCompatMode = true; } mSoftInputMode = attrs.softInputMode; mWindowAttributesChanged = true; mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED; mAttachInfo.mRootView = view; mAttachInfo.mScalingRequired = mTranslator != null; mAttachInfo.mApplicationScale = mTranslator == null ? 1.0f : mTranslator.applicationScale; if (panelParentView != null) { mAttachInfo.mPanelParentWindowToken = panelParentView.getApplicationWindowToken(); } mAdded = true; int res; /* = WindowManagerImpl.ADD_OKAY; */ //在这里开始启用绘制线程,requestLayout会触发整个的绘制过程 requestLayout(); if ((mWindowAttributes.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { mInputChannel = new InputChannel(); } try { mOrigWindowType = mWindowAttributes.type; mAttachInfo.mRecomputeGlobalAttributes = true; collectViewAttributes(); //mWindow是ViewRootImpl中的一个静态类,这个类可以用来和WindowSession交互,就等于间接在和WindowManagerService交互 //是一个桥梁类 res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mInputChannel); } catch (RemoteException e) { mAdded = false; mView = null; mAttachInfo.mRootView = null; mInputChannel = null; mFallbackEventHandler.setView(null); unscheduleTraversals(); setAccessibilityFocus(null, null); throw new RuntimeException("Adding window failed", e); } finally { if (restore) { attrs.restore(); } } if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets); } mPendingOverscanInsets.set(0, 0, 0, 0); mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingVisibleInsets.set(0, 0, 0, 0); if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow); //在这里处理WindowManagerServices的处理结果,在这里你能看到很多熟悉的异常 if (res < WindowManagerGlobal.ADD_OKAY) { mAttachInfo.mRootView = null; mAdded = false; mFallbackEventHandler.setView(null); unscheduleTraversals(); setAccessibilityFocus(null, null); switch (res) { case WindowManagerGlobal.ADD_BAD_APP_TOKEN: case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN: throw new WindowManager.BadTokenException( "Unable to add window -- token " + attrs.token + " is not valid; is your activity running?"); case WindowManagerGlobal.ADD_NOT_APP_TOKEN: throw new WindowManager.BadTokenException( "Unable to add window -- token " + attrs.token + " is not for an application"); case WindowManagerGlobal.ADD_APP_EXITING: throw new WindowManager.BadTokenException( "Unable to add window -- app for token " + attrs.token + " is exiting"); case WindowManagerGlobal.ADD_DUPLICATE_ADD: throw new WindowManager.BadTokenException( "Unable to add window -- window " + mWindow + " has already been added"); case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED: // Silently ignore -- we would have just removed it // right away, anyway. return; case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON: throw new WindowManager.BadTokenException( "Unable to add window " + mWindow + " -- another window of this type already exists"); case WindowManagerGlobal.ADD_PERMISSION_DENIED: throw new WindowManager.BadTokenException( "Unable to add window " + mWindow + " -- permission denied for this window type"); case WindowManagerGlobal.ADD_INVALID_DISPLAY: throw new WindowManager.InvalidDisplayException( "Unable to add window " + mWindow + " -- the specified display can not be found"); case WindowManagerGlobal.ADD_INVALID_TYPE: throw new WindowManager.InvalidDisplayException( "Unable to add window " + mWindow + " -- the specified window type is not valid"); } throw new RuntimeException( "Unable to add window -- unknown error code " + res); } if (view instanceof RootViewSurfaceTaker) { mInputQueueCallback = ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue(); } if (mInputChannel != null) { if (mInputQueueCallback != null) { mInputQueue = new InputQueue(); mInputQueueCallback.onInputQueueCreated(mInputQueue); } mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper()); } //给DecorView绑定mParent参数 view.assignParent(this); mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0; mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0; //判断辅助功能是否可用 if (mAccessibilityManager.isEnabled()) { mAccessibilityInteractionConnectionManager.ensureConnection(); } if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } // Set up the input pipeline. CharSequence counterSuffix = attrs.getTitle(); mSyntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage); InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage, "aq:native-post-ime:" + counterSuffix); InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage); InputStage imeStage = new ImeInputStage(earlyPostImeStage, "aq:ime:" + counterSuffix); InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage); InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage, "aq:native-pre-ime:" + counterSuffix); mFirstInputStage = nativePreImeStage; mFirstPostImeInputStage = earlyPostImeStage; mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix; } } }
本篇内容很简单,仅仅是个大绘制流程的初始化工作,接下来会着重分析performTraversals函数,在这个函数中包含了View的onMeasure,onLayout,onDraw的调用
是View重绘过程中很重要的一个函数
[Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法的更多相关文章
- [Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法
博客首页:http://www.cnblogs.com/kezhuang/p/关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下<[Andr ...
- [Android FrameWork 6.0源码学习] View的重绘过程之Draw
View绘制的三部曲,测量,布局,绘画现在我们分析绘画部分测量和布局 在前两篇文章中已经分析过了.不了解的可以去我的博客里找一下 下面进入正题,开始分析调用以及函数原理 private void pe ...
- [Android FrameWork 6.0源码学习] View的重绘过程
View绘制的三部曲, 测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...
- [Android FrameWork 6.0源码学习] View的重绘过程之Layout
View绘制的三部曲,测量,布局,绘画现在我们分析布局部分测量部分在上篇文章中已经分析过了.不了解的可以去我的博客里找一下 View的布局和测量一样,都是从ViewRootImpl中发起,ViewRo ...
- [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 ...
- Android View的重绘ViewRootImpl的setView方法
博客首页:http://www.cnblogs.com/kezhuang/p/ 本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作 /i* ...
- 【Spark2.0源码学习】-1.概述
Spark作为当前主流的分布式计算框架,其高效性.通用性.易用性使其得到广泛的关注,本系列博客不会介绍其原理.安装与使用相关知识,将会从源码角度进行深度分析,理解其背后的设计精髓,以便后续 ...
随机推荐
- Java 对IP请求进行限流.
高并发系统下, 有三把利器 缓存 降级 限流. 缓存: 将常用数据缓存起来, 减少数据库或者磁盘IO 降级: 保护核心系统, 降低非核心业务请求响应 限流: 在某一个时间窗口内对请求进行限速, 保护系 ...
- Fiddler抓取https设置及其原理
iddler抓取https设置及其原理 2018-02-02 目录 1 HTTPS握手过程2 Fiddler抓取HTTPS过程3 Fiddler抓取HTTPS设置参考 数字签名是什么? 1 HTTPS ...
- java接口----继承(实现)方法
文中"实现"一词特指接口的继承. 一个类实现多个接口时,不能出现同名的默认方法. 一个类既要实现接口又要继承抽象类,先继承后实现. 一个抽象类可以继承多个接口(implements ...
- php seaslog的使用
今天有幸在慕课网看到了 关于php日志处理工具 seasLog 的使用视频,本着好奇看完了该视频,觉得不错,便自己也倒腾了下,现在整理出来 seaslog github: https://githu ...
- python数据库连接池设计
一.背景: 传统访问资源,一般分为一下几个步骤: 1.实例数据驱动对象与链接资源.2.实例操作资源游标.3.获取资源.4.关闭链接资源. 根据以上步骤,我们可以很简单使用这个原始方法来访问资源为我们业 ...
- 简单探讨 javascript 闭包
函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个对Array的求和.通常情况下,求和的函数是这样定义的: function sum(arr) { ret ...
- Devstack 安装OpenStack Pike版本(单机环境)
问题背景 最近在研究OpenStack的时候,需要对其源代码进行调试,公司服务器上部署的OpenStack环境又不能随意的进行折腾,为了研究的持续性和方便性,就决定再自己的虚拟机上面使用Devstac ...
- js中判定this的规则
判定this new绑定:新建对象; var bar = new foo(); 明确绑定(call.apply,bind):指定对象; var bar = foo.call(obj) 隐含绑定:环境对 ...
- 剑指Offer-链表中环的入口结点
package LinkedList; import java.util.HashSet; /** * 链表中环的入口结点 * 一个链表中包含环,请找出该链表的环的入口结点. */ public cl ...
- 在java或 js中的日期时间转换问题
1.在js中需要求的当前日期的周一和周日 var now = new Date(); // 当前日期时间对象 var date = now.getDate(); // 当前是几号:当前日期在一个月中的 ...