017.View与窗口:AttachInfo
每一个View都需要依赖于窗口来显示,而View和窗口的关系则是放在View.AttachInfo中,关于View.AttachInfo的文章少,因为这个是View的内部类而且不是公共的,在应用层用的很少,只有在ViewRootImpl等类中才用到了,不过我觉得这个还是有点学习的必要,因此在这篇文章中就从源码入手学习下AttachInfo这个类。
AttachInfo 看到这个类名,我们就知道,他是代表着绑定的信息,View.AttachInfo
里面的信息,就是View和Window之间的信息。每一个被添加到窗口上的View我们都会看到有一个AttachInfo,比如我们看DecorView和Window的绑定,可以在ViewRootImpl#perfromTraversals方法中看到:
- final View.AttachInfo attachInfo = mAttachInfo;
- final int viewVisibility = getHostVisibility();
- boolean viewVisibilityChanged = mViewVisibility != viewVisibility
- || mNewSurfaceNeeded;
- WindowManager.LayoutParams params = null;
- if (mWindowAttributesChanged) {
- mWindowAttributesChanged = false;
- surfaceChanged = true;
- params = lp;
- }
- CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
- if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
- params = lp;
- mFullRedrawNeeded = true;
- mLayoutRequested = true;
- if (mLastInCompatMode) {
- params.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
- mLastInCompatMode = false;
- } else {
- params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
- mLastInCompatMode = true;
- }
- }
- mWindowAttributesChangesFlag = 0;
- Rect frame = mWinFrame;
- if (mFirst) {
- mFullRedrawNeeded = true;
- mLayoutRequested = true;
- if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL
- || lp.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD) {
- // NOTE -- system code, won't try to do compat mode.
- Point size = new Point();
- mDisplay.getRealSize(size);
- desiredWindowWidth = size.x;
- desiredWindowHeight = size.y;
- } else {
- DisplayMetrics packageMetrics =
- mView.getContext().getResources().getDisplayMetrics();
- desiredWindowWidth = packageMetrics.widthPixels;
- desiredWindowHeight = packageMetrics.heightPixels;
- }
- // For the very first time, tell the view hierarchy that it
- // is attached to the window. Note that at this point the surface
- // object is not initialized to its backing store, but soon it
- // will be (assuming the window is visible).
- attachInfo.mSurface = mSurface;
- // We used to use the following condition to choose 32 bits drawing caches:
- // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
- // However, windows are now always 32 bits by default, so choose 32 bits
- attachInfo.mUse32BitDrawingCache = true;
- attachInfo.mHasWindowFocus = false;
- attachInfo.mWindowVisibility = viewVisibility;
- attachInfo.mRecomputeGlobalAttributes = false;
- viewVisibilityChanged = false;
- mLastConfiguration.setTo(host.getResources().getConfiguration());
- mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
- // Set the layout direction if it has not been set before (inherit is the default)
- if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
- host.setLayoutDirection(mLastConfiguration.getLayoutDirection());
- }
- host.dispatchAttachedToWindow(attachInfo, 0);
- static class AttachInfo {
- interface Callbacks {
- void playSoundEffect(int effectId);
- boolean performHapticFeedback(int effectId, boolean always);
- }
- /**
- * InvalidateInfo is used to post invalidate(int, int, int, int) messages
- * to a Handler. This class contains the target (View) to invalidate and
- * the coordinates of the dirty rectangle.
- *
- * For performance purposes, this class also implements a pool of up to
- * POOL_LIMIT objects that get reused. This reduces memory allocations
- * whenever possible.
- */
- static class InvalidateInfo {
- private static final int POOL_LIMIT = 10;
- private static final SynchronizedPool<InvalidateInfo> sPool =
- new SynchronizedPool<InvalidateInfo>(POOL_LIMIT);
- View target;
- int left;
- int top;
- int right;
- int bottom;
- public static InvalidateInfo obtain() {
- InvalidateInfo instance = sPool.acquire();
- return (instance != null) ? instance : new InvalidateInfo();
- }
- public void recycle() {
- target = null;
- sPool.release(this);
- }
- }
- final IWindowSession mSession;
- final IWindow mWindow;
- final IBinder mWindowToken;
- final Display mDisplay;
- final Callbacks mRootCallbacks;
- HardwareCanvas mHardwareCanvas;
- IWindowId mIWindowId;
- WindowId mWindowId;
- /**
- * The top view of the hierarchy.
- */
- View mRootView;
- IBinder mPanelParentWindowToken;
- Surface mSurface;
- boolean mHardwareAccelerated;
- boolean mHardwareAccelerationRequested;
- HardwareRenderer mHardwareRenderer;
- boolean mScreenOn;
- /**
- * Scale factor used by the compatibility mode
- */
- float mApplicationScale;
- /**
- * Indicates whether the application is in compatibility mode
- */
- boolean mScalingRequired;
- /**
- * If set, ViewRootImpl doesn't use its lame animation for when the window resizes.
- */
- boolean mTurnOffWindowResizeAnim;
- /**
- * Left position of this view's window
- */
- int mWindowLeft;
- /**
- * Top position of this view's window
- */
- int mWindowTop;
- /**
- * Indicates whether views need to use 32-bit drawing caches
- */
- boolean mUse32BitDrawingCache;
- /**
- * For windows that are full-screen but using insets to layout inside
- * of the screen areas, these are the current insets to appear inside
- * the overscan area of the display.
- */
- final Rect mOverscanInsets = new Rect();
- /**
- * For windows that are full-screen but using insets to layout inside
- * of the screen decorations, these are the current insets for the
- * content of the window.
- */
- final Rect mContentInsets = new Rect();
- /**
- * For windows that are full-screen but using insets to layout inside
- * of the screen decorations, these are the current insets for the
- * actual visible parts of the window.
- */
- final Rect mVisibleInsets = new Rect();
- /**
- * The internal insets given by this window. This value is
- * supplied by the client (through
- * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
- * be given to the window manager when changed to be used in laying
- * out windows behind it.
- */
- final ViewTreeObserver.InternalInsetsInfo mGivenInternalInsets
- = new ViewTreeObserver.InternalInsetsInfo();
- /**
- * Set to true when mGivenInternalInsets is non-empty.
- */
- boolean mHasNonEmptyGivenInternalInsets;
- /**
- * All views in the window's hierarchy that serve as scroll containers,
- * used to determine if the window can be resized or must be panned
- * to adjust for a soft input area.
- */
- final ArrayList<View> mScrollContainers = new ArrayList<View>();
- final KeyEvent.DispatcherState mKeyDispatchState
- = new KeyEvent.DispatcherState();
- /**
- * Indicates whether the view's window currently has the focus.
- */
- boolean mHasWindowFocus;
- /**
- * The current visibility of the window.
- */
- int mWindowVisibility;
- /**
- * Indicates the time at which drawing started to occur.
- */
- long mDrawingTime;
- /**
- * Indicates whether or not ignoring the DIRTY_MASK flags.
- */
- boolean mIgnoreDirtyState;
- /**
- * This flag tracks when the mIgnoreDirtyState flag is set during draw(),
- * to avoid clearing that flag prematurely.
- */
- boolean mSetIgnoreDirtyState = false;
- /**
- * Indicates whether the view's window is currently in touch mode.
- */
- boolean mInTouchMode;
- /**
- * Indicates that ViewAncestor should trigger a global layout change
- * the next time it performs a traversal
- */
- boolean mRecomputeGlobalAttributes;
- /**
- * Always report new attributes at next traversal.
- */
- boolean mForceReportNewAttributes;
- /**
- * Set during a traveral if any views want to keep the screen on.
- */
- boolean mKeepScreenOn;
- /**
- * Bitwise-or of all of the values that views have passed to setSystemUiVisibility().
- */
- int mSystemUiVisibility;
- /**
- * Hack to force certain system UI visibility flags to be cleared.
- */
- int mDisabledSystemUiVisibility;
- /**
- * Last global system UI visibility reported by the window manager.
- */
- int mGlobalSystemUiVisibility;
- /**
- * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener
- * attached.
- */
- boolean mHasSystemUiListeners;
- /**
- * Set if the window has requested to extend into the overscan region
- * via WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN.
- */
- boolean mOverscanRequested;
- /**
- * Set if the visibility of any views has changed.
- */
- boolean mViewVisibilityChanged;
- /**
- * Set to true if a view has been scrolled.
- */
- boolean mViewScrollChanged;
- /**
- * Global to the view hierarchy used as a temporary for dealing with
- * x/y points in the transparent region computations.
- */
- final int[] mTransparentLocation = new int[2];
- /**
- * Global to the view hierarchy used as a temporary for dealing with
- * x/y points in the ViewGroup.invalidateChild implementation.
- */
- final int[] mInvalidateChildLocation = new int[2];
- /**
- * Global to the view hierarchy used as a temporary for dealing with
- * x/y location when view is transformed.
- */
- final float[] mTmpTransformLocation = new float[2];
- /**
- * The view tree observer used to dispatch global events like
- * layout, pre-draw, touch mode change, etc.
- */
- final ViewTreeObserver mTreeObserver = new ViewTreeObserver();
- /**
- * A Canvas used by the view hierarchy to perform bitmap caching.
- */
- Canvas mCanvas;
- /**
- * The view root impl.
- */
- final ViewRootImpl mViewRootImpl;
- /**
- * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
- * handler can be used to pump events in the UI events queue.
- */
- final Handler mHandler;
- /**
- * Temporary for use in computing invalidate rectangles while
- * calling up the hierarchy.
- */
- final Rect mTmpInvalRect = new Rect();
- /**
- * Temporary for use in computing hit areas with transformed views
- */
- final RectF mTmpTransformRect = new RectF();
- /**
- * Temporary for use in transforming invalidation rect
- */
- final Matrix mTmpMatrix = new Matrix();
- /**
- * Temporary for use in transforming invalidation rect
- */
- final Transformation mTmpTransformation = new Transformation();
- /**
- * Temporary list for use in collecting focusable descendents of a view.
- */
- final ArrayList<View> mTempArrayList = new ArrayList<View>(24);
- /**
- * The id of the window for accessibility purposes.
- */
- int mAccessibilityWindowId = View.NO_ID;
- /**
- * Flags related to accessibility processing.
- *
- * @see AccessibilityNodeInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
- * @see AccessibilityNodeInfo#FLAG_REPORT_VIEW_IDS
- */
- int mAccessibilityFetchFlags;
- /**
- * The drawable for highlighting accessibility focus.
- */
- Drawable mAccessibilityFocusDrawable;
- /**
- * Show where the margins, bounds and layout bounds are for each view.
- */
- boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
- /**
- * Point used to compute visible regions.
- */
- final Point mPoint = new Point();
- /**
- * Used to track which View originated a requestLayout() call, used when
- * requestLayout() is called during layout.
- */
- View mViewRequestingLayout;
- /**
- * Creates a new set of attachment information with the specified
- * events handler and thread.
- *
- * @param handler the events handler the view must use
- */
- AttachInfo(IWindowSession session, IWindow window, Display display,
- ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
- mSession = session;
- mWindow = window;
- mWindowToken = window.asBinder();
- mDisplay = display;
- mViewRootImpl = viewRootImpl;
- mHandler = handler;
- mRootCallbacks = effectPlayer;
- }
- }
首先是声明了回调接口类:callBacks 这个类第一个是playSoundEffect ,这个用于播放按键声音,参数是这个点击事件的类型,可以看SoundEffectConstants中的声明,一般是SoundEffectConstants中几个常量中的一个,在AttachInfo有一个CallBack对象
:mRootCallBacks 这个的实现可以看ViewRootImpl类,ViewRootImpl中,我们可以看到:
- public void playSoundEffect(int effectId) {
- checkThread();
- if (mMediaDisabled) {
- return;
- }
- try {
- final AudioManager audioManager = getAudioManager();
- switch (effectId) {
- case SoundEffectConstants.CLICK:
- audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
- return;
- case SoundEffectConstants.NAVIGATION_DOWN:
- audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN);
- return;
- case SoundEffectConstants.NAVIGATION_LEFT:
- audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT);
- return;
- case SoundEffectConstants.NAVIGATION_RIGHT:
- audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT);
- return;
- case SoundEffectConstants.NAVIGATION_UP:
- audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP);
- return;
- default:
- throw new IllegalArgumentException("unknown effect id " + effectId +
- " not defined in " + SoundEffectConstants.class.getCanonicalName());
- }
- } catch (IllegalStateException e) {
- // Exception thrown by getAudioManager() when mView is null
- Log.e(TAG, "FATAL EXCEPTION when attempting to play sound effect: " + e);
- e.printStackTrace();
- }
- }
feedBackContants )这个方法,当然,如果我们调用performHapticFeedback(int feedbackConstant, int flags) 的时候,把参数FLAG_IGNORE_GLOBAL_SETTING 就可以忽略全局设置,而如果我们HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING 就可以忽略我们在View里面设置的android:hapticFeedbackEnabled
- <span style="white-space:pre"> </span>final IWindowSession mSession;
- <span style="white-space:pre"> </span>
- final IWindow mWindow;
- final IBinder mWindowToken;
- IBinder mPanelParentWindowToken ;
来获取的
、IWindow 、mWindowToken 都是从IWindowManager.Stub.asInterface(ServiceManager.getService("window"))获取到IWindowManager来获取的。
的DecorView 的AttachInfo这个值就是null,而我们弹出了一个对话框,这个对话框的这个就不为null,因为这个对话框是有父窗口的。
017.View与窗口:AttachInfo的更多相关文章
- 使用WindowManager添加View——悬浮窗口的基本原理
Android系统中的“窗口”类型虽然很多,但只有两大类是经常使用的:一是由系统进程管理的,称之为“系统窗口”:第二个就是由应用程序产生的,用于显示UI界面的“应用窗口”.如果大家熟悉WindowMa ...
- 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)
Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...
- Android 的窗口管理系统 (View, Canvas, WindowManager)
http://blog.csdn.net/ritterliu/article/details/39295271 From漫天尘沙 在图解Android - Zygote 和 System Server ...
- go语言使用go-sciter创建桌面应用(七) view对象常用方法,文件选择,窗口弹出,请求
view对象的详细文档请看: https://sciter.com/docs/content/sciter/View.htm demo9.html代码如下: <!DOCTYPE html> ...
- 浅析 Android 的窗口
来源:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=555&fromuid=6 一.窗口的概念 在开发过程中,我们经常会 ...
- 浅析Android的窗口
一.窗口的概念 在开发过程中,我们经常会遇到,各种跟窗口相关的类,或者方法.但是,在 Android 的框架设计中,到底什么是窗口?窗口跟 Android Framework 中的 Window 类又 ...
- Android10_原理机制系列_Activity窗口添加到WMS过程
前言 首先看一个Android界面的布局层次结构,最直观的看一下: 我们能清晰看到,这个界面分成了3部分:顶部状态栏(statusbar).底部导航栏(navigationbar).应用界面. 题外话 ...
- Android 浮窗开发之窗口层级
很多人都知道如何去实现一个简单的浮窗,但是却很少有人去深入的研究背后的流程机制,由于项目中浮窗交互比较复杂,遇到了些坑查看了很多资料,故总结浮窗涉及到的知识点: 窗口层级关系(浮窗是如何"浮 ...
- iOS开发——UI进阶篇(八)pickerView简单使用,通过storyboard加载控制器,注册界面,通过xib创建控制器,控制器的view创建,导航控制器的基本使用
一.pickerView简单使用 1.UIPickerViewDataSource 这两个方法必须实现 // 返回有多少列 - (NSInteger)numberOfComponentsInPicke ...
随机推荐
- Python虚拟机函数机制之参数类别(三)
参数类别 我们在Python虚拟机函数机制之无参调用(一)和Python虚拟机函数机制之名字空间(二)这两个章节中,分别PyFunctionObject对象和函数执行时的名字空间.本章,我们来剖析一下 ...
- Linux的档案权限与目录配置
重点回顾:1.Linux的每个档案中,依据权限分为使用者.群组与其他人三种身份 2.群组最有用的功能之一,就是当你在团队开发资源的时候,且每个账号都可以有多个群组的支持 3.利用"ls -l ...
- 06-python进阶-多线程下载器练手
我们需要用python 写一个多线程的下载器 我们要先获取这个文件的大小 然后将其分片 然后启动多线程 分别去下载 然后将其拼接起来 #!/usr/bin/env python#coding:utf- ...
- python补漏----isinstance 和 issubclass
一.isinstance Python 中的isinstance函数 isinstance是Python中的一个内建函数 语法: isinstance(object, classinfo) 如果参数o ...
- 如何用jquery+json来写页面
以下是json数据表: [ { "p" : "银川市", "c" : [{"c1":"兴庆区"},{ ...
- hibernate缓存详解
hibernate中提供了两级缓存,一级缓存是Session级别的缓存,它属于事务范围的缓存,该级缓存由hibernate管理,应用程序无需干预:二级缓存是SessionFactory级别的缓存,该级 ...
- Java容器jdk1.6 Array
参考:https://www.cnblogs.com/tstd/p/5042087.html 1.定义 顶层接口collection public interface Collection<E& ...
- JavaScriptCore 简介
转自http://esoftmobile.com/2013/06/19/integrating-javascript-into-native-applications/ Integrating Jav ...
- webstorm自带debugger服务器
打开webstorm->settings->Build,Execution,Deployment->Debugger->把端口Port改成8089或者其他80端口,按确定就可以 ...
- 周赛Problem 1021: 分蛋糕(埃拉托斯特尼筛法)
Problem 1021: 分蛋糕 Time Limits: 1000 MS Memory Limits: 65536 KB 64-bit interger IO format: %lld ...