正在陪女儿画画的我,被女儿问到: ?:“爸爸,妈妈说你的工作是可以把我们想到的东西变到手机上,是这样吗?” ?:“对呀,厉害吧~” ?:“那你可以把我们家的小狗狗变到手机上吗?” ?...View.invalidate/postInvalidate 还有一种触发绘制的情况就是View.invalidate/postInvalidate,postInvalidate一般用于子线程,最后也会调用到...= null); } } 一个dowhile循环,不断调用父View的invalidateChildInParent方法。...,只有不为空的话才会继续执行下去。...继续看draw(Canvas canvas)方法,注释还是比较清晰的,一共分为了六步: 1、绘制背景 2、保存图层信息 3、绘制内容(onDraw) 4、绘制children 5、绘制边缘 6、绘制装饰
1、首先先说一下我们在自定义View中可能会犯的3个错误: 1)Useless calls to onDraw():我们知道调用View.invalidate()会触发View的重绘,有两个原则需要遵守...3)Wasted CPU cycles:对于不在屏幕上的元素,可以使用Canvas.quickReject把他们给剔除,避免浪费CPU资源。...设备有一定的刷新频率,导致View的onDraw方法会被频繁的调用,如果onDraw方法效率低下,在频繁刷新累积的效 应下,效率低的问题会被扩大,然后会对性能有严重 的影响。 ...只有view内容改变的时候,调用invalidate()方法更新界面。 对于不在屏幕上的元素,可以调用Canvas.quickReject()方法剔除,避免资源浪费。 ...例如当你滑动界面的时候,系统就会频繁的调用onDraw()方法,这是就会在短时间内占有大量的内存。会出现内存抖动,GC会频频的触发,会影响到CPU的效率,并且会造成 手机电量的大量消耗。
“操作UI”理解成“调用View.invalidate()”。 问题也就变成了:子线程能否调用View.invalidate()。...二、View.invalidate() 接下来分析一下View.invalidate()代码 代码2.1 public void invalidate() { invalidate...(this, damage); 三、ViewRootImpl.invalidateChild 继续研究ViewRootImpl.invalidateChild的代码逻辑 @Override public...我们好好思考一下代码2.1中两处代码 4.1 skipInvalidate if (skipInvalidate()) {//判断是否需要跳过绘制 return;...} //判断是否需要可见或者处于动画中 private boolean skipInvalidate() { return (mViewFlags &
前言 今天继续说绘制三部曲之最后一曲——draw。...) 4、绘制children 5、绘制边缘 6、绘制装饰 其中,第三步也就是我们自定义View必用的onDraw方法,在该方法中,需要我们绘制View本身的内容。...绘制时钟表盘和中心点 下面就开始进行onDraw方法里面的内容,首先就是表盘和中心点。...比如上述的canvas.rotate方法,在这之前需要调用save保存画布的原始状态,最后在调用restore方法恢复画布,完整调用链如下: canvas.save() //... canvas.rotate...= null) { view.getNowtime() view.invalidate()
很开心的是,RandomTextView继承自TextView所以可以使用TextView的所有方法。color,size等等直接去定义就OK啦。 所有位数相同速度滚动: ?...去绘制出来,在绘制的Y坐标不断增加偏移量,去改变绘制的高度,通过handler.postDelayed(this, 20);不断增加偏移量,并且不断判断所有位数字最后一行绘制完毕的时候,结束handler...的循环调用。...以上就是进入i循环先对是否绘制结束的判断。 如果没有结束那么继续绘制。...onDraw方法会随着你view的帧数不断的被调用,一秒可能被执行几十次。
【UI线程】:实例化ViewRootImpl的线程,最终执行View的onMeasure/onLayout/onDraw等涉及UI操作的线程。...View的Parent,同时该View也被认定为rootView。...public void invalidate() { invalidate(true); } 3.4 深入观察ViewRootImpl及Android屏幕刷新机制 我们不妨将问题换一个表述:是否可以安全地不在主线程中更新...mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); // ... } Choreographer被调用后...performDraw(); } 那么整个绘制流程中的UI线程是否一致呢?绘制过程中是否有强行取用主线程(mainThread)的情况?
因为绘图相关对象的创建都比较耗费性能,而onDraw方法调用频率很gao(PieChart是可以转动的,每次转动都需要重新执行onDraw)。...result = true; } } return result; } GestureDetector.onTouchEvent返回值表示此事件是否被处理...(这是API 11中View类引入的方法,之前的版本可以通过canvas.rotate完成,但这样的话操作就需要在onDraw中执行,为了通知系统执行某个View的onDraw方法,执行View.invalidate...onDraw中根据条件继续调用invalidate:这个不是定时去执行onDraw,而是每次onDraw之后如果发现还需要执行动画就继续触发下一次onDraw。...Scroller是一个持有位置数据,并提供操作改变这些数据的类,具体的执行频率是调用者的事情,可以使用handler、动画等方式实现周期性来不断调用它的computeScrollOffset来获得更新后的位置
在不借助Animation所提供的API时,我们可以定义一个当前时间开始的300ms的倒计时,然后调用invalidate通知onDraw的执行,之后在onDraw中根据是否过期来继续执行invalidate...又是如何在动画运行期间被不断调用的?...如果getTransformation返回true,将继续执行parent.invalidate语句,它使得View对应画布的区域被标记为失效,这样后续会执行一次onDraw来重绘。...注意drawAnimation继续返回getTransformation相同含义的返回值——动画是否还在运行——给调用者,那么继续看看更上面的方法如何使用它。...2.8 draw中根据其返回值决定是否继续调用invalidate触发下一次动画绘制。如果为true就继续执行invalidate方法触发下一次动画绘制,否则动画结束。
所以我不会直接进入主题,让我们先从 View.invalidate() 说起。...从 View.invalidate() 说起 要探究屏幕刷新机制和 View 绘制流程,View.invalidate() 无疑是个好选择,它会发起一次绘制流程。...为了探究 View 的刷新流程,我们跟着 View.invalidate() 方法一路追到 ViewGroup.invalidateChild() ,其中递归调用 parent 的 invalidateChildInParent...mChoreographer 是如何发送任务以及任务是如何被调度执行的? 围绕这三个问题,我们再回到源码中。...总结一下: 从 View.invalidate() 开始,最后会递归调用 parent.invalidateChildInParent() 方法。
performance 原文作者: Daniel Lew 译文出自: 小鄧子的简书 译者: 小鄧子 校对者: 泡网编辑 状态: 完成 当有人问我关于动画性能表现不佳问题的时候,我首先会询问他们是否使用了...因为许多动画都是多种变换的组合,所以使用View Layer能够显著提高动画性能。...动画结束时,调用View.setLayerType(View.LAYER_TYPE_NONE, null)进行清理操作。...动画运行时,如果某个地方调用了View.invalidate( ),那么Layer就不得不重新渲染一遍。...由于错误的Hardware Layer用法,许多性能收益被干掉了。 (这里有一些奇怪,如果它正处在invalidating,应该至少与不使用Hardware Layer一样迟钝。
一直有各种事情,很久没更新了,趁春节空档继续更新,分享一个线上疑难问题的排查过程 在某个版本上线后,这个异常的量突然变大了,log如下 通过log,可以知道是imageview使用了被回收的bitmap...的生命周期中,我们可以在崩溃后台,标记最新可见的activity,当发生崩溃时候,把当前可见的activity一起上报,可以通过后台查看,崩溃那一刻,在前台的是哪个activity 可以连续查看几条,看下是否都是同个...方法,调用其实就是view的布局一步步调用下来的 通过上图的分析,可以知道崩溃imageview的布局层级关系,用图表示如下 可以通过activity的布局,定位到符合这个布局层级关系的imageview...到这里应该可以基本确定异常的imageview了,如果还不行,继续看步骤3 3、准确定位异常imageview 如果上面的两个步骤,还是无法定位修复问题,可以继续看 比如发现有多个imageview都满足条件...= null override fun onDraw(canvas: Canvas?)
draw方法 绘制装饰(onDrawScrollBars) isEnabled() 当前视图是否可用。...isFocused() 当前视图是否获得焦点 通常情况下有两种方法可以让视图获得焦点,即通过键盘的上下左右键切换视图,以及调用requestFocus()方法。...而现在的Android手机几乎都没有键盘了,因此基本上只可以使用requestFocus()这个办法来让视图获得焦点了。...还需要尽可能的减少onDraw被调用的次数,大多数时候导致onDraw都是因为调用了invalidate().因此请尽量减少调用invaildate()的次数。...与内置的view不同,自定义的view可以使得程序仅仅测量这一部分,这避免了遍历整个view的层级结构来计算大小。
在这里我们自定义一个GameView继承自SurfaceView 注意:因为SurfaceView虽然继承自View,但并没重写onDraw(),所以子类可以重写onDraw()但并不能自动调用。...在surfaceCreated中生成一个Thread来不断地调用draw函数,同时初始化玩家机型。另外设置接口。这个需要MainActivity来管理。...flag = true; } }); //生成一个Thread来不断地调用...判断是继续游戏还是结束 伪代码: public class MainActivity extends Activity { @Override protected void onCreate...finish(); } }) .setNegativeButton("继续
希望以后能继续和大家共同学习,共同努力,一起进步!共勉!...4.3 引用类型检查 有时候需要在运行时判断一个对象是否属于某个引用类型,这时可以使用instanceof运算符,instanceof运算符语法格式如下: obj instanceof type...代码第21行item instanceof Worker表达式是判断数组中的元素是否是Worker实例;类似地,第23行item instanceof Student表达式是判断数组中的元素是否是Student...5.2 final修饰类 final修饰的类不能被继承。有时出于设计安全的目的,不想让自己编写的类被别人继承,这是可以使用final关键字修饰父类。...有时也是出于设计安全的目的,父类中的方法不想被别人覆盖,这时可以使用final关键字修饰父类中方法。
方法一直被调用 我们在onDraw方法中添加Log日志,发现onDraw方法每间隔500ms左右被调用一次 image.png 此处先给出解决办法: *当我们继承EditText自定义验证码输入框后...,EditText自带的光标对我们来说不可见,已经没有意义,因此需要将其隐藏掉,防止onDraw方法一直被调用 isCursorVisible = false 问题分析 问题1:是什么方法一直在不停的调用...我们知道invalidate方法会触发页面重绘进而调用onDraw方法,EditText又继承TextView,在TextView源码中搜索invalidate关键字然后加断点调试运行,最后将代码锁定在...invalidateCursorPath方法,发现此方法不停被调用,代码如下: void invalidateCursorPath() { if (mHighlightPathBogus...答案1:invalidateCursorPath方法一直被调用,最后导致onDraw方法被调用 问题2:什么方法在一直调用invalidateCursorPath方法呢?
(3)另外,dispatchTouchEvent()方法中还有“记忆”的功能,如果第一次事件向下传递到某View,它把事件继续传递交给它的子View,它会记录该事件是否被它下面的View给处理成功了,(...()方法机会判断,若上次的事件由下面的view成功处理了,那么这次的事件就继续交给下面的来处理,若上次的事件没有被下面的处理成功,那么这次的事件就不会向下传递了,该View直接调用自己的onTouchEvent...3、双进程Service:让2个进程互相保护,其中一个Service被清理后,另外没被清理的进程可以立即重启进程 4、AlarmManager不断启动service。...你还需要尽可能的减少onDraw被调用的次数,大多数时候导致onDraw都是因为调用了invalidate().因此请尽量减少调用invaildate()的次数。...在其next()中会无限循环,不断判断是否有消息,有就返回这条消息并移除。
调用 performDraw方法 其执行的过程可简单的概括为:是否需要重新计算视图的大小(measure)、是否需要重新布局视图的位置(layout),以及是否需要重绘(Draw),也就是我们常说的...是否需要绘制边框渐变效果 假如我们需要绘制视图View的边框渐变效果,那么我们继续分析步骤2,3,4,5,6。 ?...然后接着绘制当前视图的内容,调用了onDraw方法: ? View的onDraw方法 发现该方法为空,主要在子类中实现,继续看DecorView的onDraw方法: ?...DecorView的onDraw方法 当前视图的内容绘制完成后,接着绘制子视图的内容,调用了dispatchDraw方法。 ?...View的drawChild方法 这个draw方法也是View里面的方法,被drawChild()方法调用: ?
既然一个 View 中 onDraw() 方法获取到的 Canvas 已经经过了坐标系的变换,那么如果要追踪下去,肯定就是要调查 View.onDraw() 方法被谁调用。...好,我们继续向下。...因为 computeScrollOffset() 被不断地调用,所以 Scroller 中的 mCurrentX 和 mCurrentY 被不断地被更新,所以 Scroller 动画就能够跑去起来。...不过,没有完,继续解疑。...2.在 onDraw() 方法中调用 postInvalidate() 方法,可以导致 onDraw() 方法不断重绘。 显然,我们在这里采取的是第二种方法。
领取专属 10元无门槛券
手把手带您无忧上云