项目中用到一个自定义View,功能类似于跑马灯。但是在低端机上有明显的卡顿,故拿出部分代码做优化。代码如下
代码语言:javascript复制 override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (!TextUtils.isEmpty(mText) && mValueAnimator?.isRunning == true && mStartY != -1) {
val x = mWidth - (mWidth mPaint.measureText(mText)) * mFraction
val y = mStartY.toFloat()
canvas.drawText(mText, x, y, mPaint)
}
}
通过查看 Android Profiler,可以知道
代码语言:javascript复制onDraw total = 6.7 self = 2.3 children = 4.4
6.1 1.7 4.3
6.4 2.0 4.3
6.6 2 4.6
onDraw里面,很明显 self 里面的计算占了 2% 左右,其实可以优化. measureText 可以放到外面 canvas.drawText 占了4.5%左右,这一部分也可以优化
代码语言:javascript复制 override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (mValueAnimator?.isRunning == true && mStartY != -1) {
canvas.clipRect(0, mCLipTop, width, mCLipBottom)//限制在规定的区域内重绘
val x = mWidth - (mWidth mTxtWidth) * mFraction
val y = mStartY.toFloat()
canvas.drawText(mText, x, y, mPaint)
}
}
如上修改以后, self 降到 1% 左右,.同时 children 也降到 3% 左右(可见 canvas.drawText 还是很占CPU的) 从技术角度能做的优化其实已经差不多了,但是从需求的角度还是有优化的空间的 这个自定义View的功能就是跑马灯,就是让文字随着时间走.那么就可以想到两种解决方案 (1)画布移动 canvas.translate 这个方案的问题就是 translate 之后还是要 drawText, 还是很占CPU (2)整体移动 View, 也就是在 TextView 的基础上修改, 用 scrollTo 来处理
最终方案
代码语言:javascript复制 override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (mValueAnimator?.isRunning == true) {
val x = mWidth - (mWidth mTxtWidth) * mFraction
scrollTo(-x.toInt(), 0)
}
}
自定义View的优化最重要的就是一开始的时候选择相对好一点的实现方式,这样后期的优化工作可以少一些