那么既然出现了这个错误,总得有原因吧,或许是自己源码看漏了?...String packageName = mView.getContext().getOpPackageName(); if (context == null) {...,那么为什么ViewRootImpl是null呢,明明之前已经show过了。...=" + mView); if (mView !...if (mView.getParent() != null) { if (localLOGV) Log.v(TAG, "REMOVE!
分析上述代码我们需要先确定 mView 指代的含义,再我们继续分析之前。...先有如下猜想: 1、 mView 是获得焦点的 View; 2、mView 是顶层的 DecorView; 我们通过查找 mView 的实例,很容易找到 setView 方法。...这个方法将 mView 与 ViewRootImpl 互相绑定,mView 的身份已经呼之欲出了。但是在没有足够的证据(代码)说明之前,我们对结果仍保持怀疑。...) { synchronized (this) { if (mView == null) { mView = view;...= null) { mDeadWindowEventReceiver.dispose(); mDeadWindowEventReceiver = null
文章目录 一、Canvas 绘图源码分析 二、ViewRootImpl#draw 方法源码 三、ViewRootImpl#drawSoftware 方法源码 Canvas 状态保存机制 中 , 存在两个栈结构...#draw 方法源码 ---- ViewRootImpl#draw 方法源码 : public final class ViewRootImpl implements ViewParent,...= null ? params.surfaceInsets : null; if (surfaceInsets !...= null && !...三、ViewRootImpl#drawSoftware 方法源码 ---- ViewRootImpl#drawSoftware 方法源码 : /** * @return true if
= null) { /*******部分代码省略**********/ if (r.window == null && !...== null) { //ViewRootImpl成员变量view进行复制,以后操作的都是mView。...= null; mAttachInfo.mRootView = null; mInputChannel = null;...对mView进行操作 对View的操作包括文章最开始讲述的测量、布局、绘制,其过程主要是在ViewRootImpl的performTraversals方法中。...//调用Window对应的ViewRootImpl的invalidate方法 mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo
= null) { final Activity a = r.activity; //... if (r.window == null && !...创建ViewRootImpl实例 ViewRootImpl root = new ViewRootImpl(view.getContext(), display);...) { synchronized (this) { if (mView == null) { mView = view; // 保存DecorView引用...执行DecorView的draw() mView.draw(canvas); } finally { // 3....区域标记需要重绘的部分减少不必要的GPU渲染开销特别优化动画场景下的性能表现五、性能优化启示1、减少布局层级每增加一层布局增加6ms测量时间使用标签或ConstraintLayout优化2、避免主线程阻塞// 错误示例
ViewRootImpl 视图层次结构的顶部。一个 Window 对应着一个 ViewRootImpl 和 一个 VIew。这个 View 就是被 ViewRootImpl 操作的。...ViewRootImpl root; View panelParentView = null; synchronized (mLock) { //创建 ViewRootImpl...panelParentView) { synchronized (this) { if (mView == null) { mView = view;...ViewRootImpl. performTraversals private void performTraversals() { // cache mView since it is used...mReportNextDraw) { return; } else if (mView == null) { return; } final boolean
每一个Window对应一个View与ViewRootImpl,它与view是通过ViewRootImpl来建立关系的,它是以view的形式存在。...View panelParentView) { synchronized (this) { if (mView == null) { mView = view...= null) { int viewVisibility = mView.getVisibility(); boolean...= null && mView.mAttachInfo !..., null); mView.assignParent(null); mView = null; mAttachInfo.mRootView = null
= null; mAttachInfo.mRootView = null; mInputChannel = null; mFallbackEventHandler.setView...(event)//按键事件 mView.dispatchPointerEvent(event) mView.dispatchTrackballEvent(event) mView.dispatchGenericMotionEvent...(event) mView的实例化是在setView方法中完成,而我们知道ViewRootImpl的setView方法中传入的view参数是DecorView,因为ViewRootImpl通过setView...所以这里的mView其实就是DecorView。...这样一来,可以知道ViewPostImeInputStage将事件分发到了View,而这里的mView又是DecorView,也就是多态的原理,如果DecorView没有上述的mView.的几个方法,就会调用
如果那里有错误大家一定指出我将不胜感激。 ---- Activity#setContentView 关于View的工作原理,大家可能会问:为什么不直接看View呢?...ViewRootImpl root; View panelParentView = null; synchronized (mLock) {...attrs, View panelParentView) { synchronized (this) { if (mView == null) {...//将顶级视图DecorView赋值给全局的mView mView = view; ................由于本人能力有限,如果有错误大家一定指出,共同进步。最后希望如果对你有帮助请评个论,点个关注,让我更有信心和动力。下篇我们将针对View的三大流程来分析下。
} ViewRootImpl root; View panelParentView = null; //创建 ViewRootImpl,并赋值给 root root...) { synchronized (this) { if (mView == null) { mView = view; //...一般不会使用 removeViewImmedialte 来删除 Window,以免发生意外错误。 所以这里使用的是 异步的删除情况,采用的是 die 方法。...if (mView !...= null) { mWindowManager.removeView(mView); } try { // 将 Toast
ViewRootImpl die(boolean immediate) boolean die(boolean immediate) { // Make sure we do execute...= null) { int viewVisibility = mView.getVisibility(); boolean...= null && mView.mAttachInfo !...= null) { mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(false); mView.dispatchDetachedFromWindow..., null); mView.assignParent(null); mView = null; mAttachInfo.mRootView = null
3.Window上何时添加View,ViewRootImpl在哪实现的? 4.ViewRootImpl是如何处理View的,它对View的测量、布局、绘制有什么关系?...ViewRootImpl root; ......== null) { mView = view;//二话不说,私家珍藏先 ......、performDraw的身上 ---->[ViewRootImpl#performMeasure]-------------------- |--看着真爽...直接让调用mView的measure...final View host = mView;//host记录一下当前View ...
() 当你拿着遥控器瞎按的时候,按键处理的起点是这儿 public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks...= null ? ...() 按键事件自动寻焦 代码回到ViewRootImpl【1.1】返回 false ,代码继续往下执行 public final class ViewRootImpl implements ViewParent...= 0) { View focused = mView.findFocus(); if (focused !...= null && v !
attrs, View panelParentView) { synchronized (this) { if (mView == null) {...(mDisplayListener, mHandler); mViewLayoutDirectionInitial = mView.getRawLayoutDirection...} catch (RemoteException e) { mAdded = false; mView...看图片,最终调用了ViewRootImpl.setView 在setview方法里调用了view.assignParent(this);将Decorview的mParent设置成ViewRootImpl...,并将DecorView的父布局设置为ViewRootImpl,然后通过ViewRootImpl的performTraversals方法绘制view
if (context == null) { context = mView.getContext(); } //获取上下文环境的...if (mView.getParent() != null) { if (localLOGV) Log.v(TAG, "REMOVE!...if (mView.getParent() != null) { if (localLOGV) Log.v(TAG, "REMOVE!...(mView); } mView = null; } } } Dialog和Toast在异步线程的展现 ViewRootImpl的独白...总结 通过分析Activity、Dialog、Toast通过对 ViewRootImpl 的更细节的分析,所有添加在窗口上的 View 都有一个 ViewRootImpl 作为它的 Parent ,处理
= null && ai !...= null && ai !...if (parent instanceof ViewRootImpl) { ((ViewRootImpl) parent).mIsAnimating =...这样的话我们就可以知道,肯定是调用到了最外层的`ViewGroup`,也就是`ViewRootImpl`,我们查看`ViewRootImpl`源码: ```java @Override...invalidate()就分析到这里了,有什么意见或者文中有什么错误的希望可以在下方评论。希望大家可以在看我的文章中可以学习到知识。
的时候在 ViewRootImpl 的构造方法中创建的: public ViewRootImpl(@UiContext Context context, Display display, IWindowSession...attrs, View panelParentView, int userId) { synchronized (this) { if (mView == null.../开始执行view的绘制流程 performTraversals(); } } private void performTraversals() { // cache mView...final View host = mView; if (mFirst) { //调用 view 该方法 host.dispatchAttachedToWindow...在 ViewRootImpl 构造方法中回创建 mAttachInfo 在 ViewRootImpl.setView 中对 mAttacheInfo 添加各种数据,并调用 View 的绘制流程,设置同步屏障
view hierarchy can touch its views."); } } 可以看到是因为当前线程currentThread不是mThread的时候,就会崩溃,报的错误是...原因就在Toast的hide方法中,最终会调用到View的assignParent方法,将Toast的mParent设置为null,也就是ViewRootImpl设置为null了。...贴下代码: public void handleHide() { if (mView != null) { if (mView.getParent() !...= null) { mWM.removeViewImmediate(mView); } mView = null; } } removeViewImmediate...= null) { view.assignParent(null); if (deferred) { mDyingViews.add(view);
每一个Window都对应着一个View和一个ViewRootImpl,Window和View通过ViewRootImpl建立联系,所以Window并不是实际存在的,而是以View的形式存在。...ViewRootImpl root; View panelParentView = null; root = new ViewRootImpl(view.getContext...); } public void handleHide() { if (mView !...= null) { if (mView.getParent() !...= null) { mWM.removeView(mView); } mView = null; }