出现 ArithmeticException:除以零,但我没有在任何地方除以零

Jaz*_*han 3 android kotlin crashlytics android-bitmap

基本上,我正在从用户存储中读取图像进行处理,在读取图像时,我正在计算 inSampleSize 以节省一些内存,这是我的代码:

fun calculateInSampleSize(
    options: BitmapFactory.Options,
    reqWidth: Int,
    reqHeight: Int
): Int {
    // Raw height and width of image
    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
        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {
            inSampleSize *= 2
        }
    }
    return inSampleSize
}
Run Code Online (Sandbox Code Playgroud)

但是,我得到 ArithmeticException: 在 while 循环条件内除以零:

halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth

我认为 inSampleSize 永远不会为零,因为它从 1 开始,并在每次迭代中乘以 2。谁能帮我看看这是怎么回事?

它只是对某些用户来说会崩溃(到目前为止大约有 13 次崩溃),而且我无法重现它。

编辑,添加崩溃日志:

Non-fatal Exception: java.lang.ArithmeticException: divide by zero
       at myapp.myapp.myapp.utils.UtilsKt.calculateInSampleSize(Utils.kt:108)
       at myapp.myapp.myapp.utils.UtilsKt$resizeImageWithPixel$2.invokeSuspend(Utils.kt:464)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
       at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
       at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:570)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Jof*_*rey 5

我认为 inSampleSize 永远不会为零,因为它从 1 开始,并在每次迭代中乘以 2。谁能帮我看看这是怎么回事?

我认为这就是你错的地方。如果你让你的整数溢出,你肯定可以通过乘以 2 足够的次数得到零:

var inSampleSize = 1
while (inSampleSize != 0) {
    println("inSampleSize = $inSampleSize")
    inSampleSize *= 2
}
println("inSampleSize is 0 now!")
Run Code Online (Sandbox Code Playgroud)

在这里亲自查看: https: //pl.kotl.in/uZHs7YQCW

inSampleSize = 1
inSampleSize = 2
inSampleSize = 4
inSampleSize = 8
inSampleSize = 16
inSampleSize = 32
inSampleSize = 64
inSampleSize = 128
inSampleSize = 256
inSampleSize = 512
inSampleSize = 1024
inSampleSize = 2048
inSampleSize = 4096
inSampleSize = 8192
inSampleSize = 16384
inSampleSize = 32768
inSampleSize = 65536
inSampleSize = 131072
inSampleSize = 262144
inSampleSize = 524288
inSampleSize = 1048576
inSampleSize = 2097152
inSampleSize = 4194304
inSampleSize = 8388608
inSampleSize = 16777216
inSampleSize = 33554432
inSampleSize = 67108864
inSampleSize = 134217728
inSampleSize = 268435456
inSampleSize = 536870912
inSampleSize = 1073741824
inSampleSize = -2147483648
inSampleSize is 0 now!
Run Code Online (Sandbox Code Playgroud)