计算Bitmap的inSampleSize时触发ArithmeticException: divide by zero异常
崩溃原因分析与解决方案
根本原因
崩溃是由于调用calculateInSampleSize时传入了负数的reqWidth或reqHeight,导致while循环无限执行,最终inSampleSize溢出为0,触发除以0的算术异常。
详细推导
- 正常逻辑中,
inSampleSize从1开始每次乘2,不会出现0,但如果reqWidth/reqHeight为负数:- while循环的判断条件
halfHeight / inSampleSize >= reqHeight会永远成立(正数必然大于等于负数),同理halfWidth / inSampleSize >= reqWidth也始终为true,循环会无限运行。
- while循环的判断条件
- Kotlin的
Int是32位有符号整数,最大值为2^31 - 1:- 当
inSampleSize不断乘2,最终会溢出:达到2^31时,数值变为-2147483648,再乘2就会溢出为0。此时循环条件判断时执行halfHeight / 0,直接抛出ArithmeticException: divide by zero。
- 当
修复方案
方案1:在函数内部添加参数合法性校验
在函数开头加入参数检查,拦截非法的负数输入:
fun calculateInSampleSize( options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int ): Int { // 校验参数必须为正整数 require(reqWidth > 0 && reqHeight > 0) { "reqWidth和reqHeight必须是正整数" } val (height: Int, width: Int) = options.run { outHeight to outWidth } var inSampleSize = 1 if (height > reqHeight || width > reqWidth) { val halfHeight: Int = height / 2 val halfWidth: Int = width / 2 while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { inSampleSize *= 2 } } return inSampleSize }
方案2:在调用处确保参数合法
检查所有调用calculateInSampleSize的地方,保证传入的reqWidth和reqHeight都是正数,避免非法参数进入计算逻辑。
内容的提问来源于stack exchange,提问作者Jazib Khan
相关产品推荐
相关产品推荐

