Android自定义View重绘Canvas调用invalidate()导致应用崩溃如何解决?
排查思路
- 输入转换异常:
submit方法中直接调用value.toFloat(),如果输入框为空、输入非数字内容,会抛出NumberFormatException直接崩溃。
修复示例:fun submit(view: View) { val text = findViewById<EditText>(R.id.editTextNumberDecimal) val canvas = findViewById<CustomCanvas>(R.id.customCanvas) val value = text.text.toString() val t = findViewById<TextView>(R.id.textView) t.text = value // 新增校验逻辑 val weight = try { value.toFloat() } catch (e: NumberFormatException) { Toast.makeText(this, "请输入合法的数字", Toast.LENGTH_SHORT).show() return } canvas.setWeightandRedraw(weight) } - Canvas空指针异常:
onDraw方法传入的Canvas是可空类型,drawBar、drawWeightKg中如果直接调用Canvas的方法,空对象会触发空指针崩溃。
修复示例:在onDraw开头先做非空校验override fun onDraw(canvas: Canvas?) { canvas ?: return drawBar(canvas) drawWeightKg(canvas, weight) } - 循环重绘导致冻结:检查
drawBar、drawWeightKg的内部实现,如果里面调用了invalidate()、postInvalidate()这类触发重绘的方法,会导致onDraw被反复调用,触发界面卡死甚至ANR。需移除绘制流程中的重绘逻辑。 - 绘制逻辑耗时导致卡顿崩溃:不要在
onDraw中创建Paint、Path这类对象,频繁重绘会导致大量临时对象被创建,引发内存抖动甚至OOM。把这类绘制相关的对象移到构造方法中初始化即可。 - 数值计算异常:如果绘制逻辑中用到了
width、height获取View的尺寸,View未完成测量时拿到的宽高为0,如果做除法运算会触发ArithmeticException崩溃,用到宽高前先判断是否大于0再执行后续逻辑。
内容的提问来源于stack exchange,提问作者Tyler B. Joudrey
相关产品推荐
相关产品推荐

