我有一个JAVA(在安卓系统上运行)的方法,它偶尔会因为被零除而捕获ArithmeticException,尽管变量inSampleSize在循环之前被设置为1,并且每次只被乘以2。下面是原样的方法。你知道我错过了什么吗?谢谢!
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
try {
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = 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;
}
}
} catch (ArithmeticException e) {
LogUtil.Log("ArithmeticException=" + e.getMessage() + " inSampleSize=" + inSampleSize);
Crashlytics.logException(e);
inSampleSize=1;
}
LogUtil.Log("inSampleSize="+inSampleSize);
return inSampleSize;
}发布于 2018-03-25 00:23:33
乍一看,如果您将一个数字初始化为1,并且只将其与2相乘,则永远不会得到0的结果。但是,在while循环的32次迭代之后,inSampleSize的值实际上将是0。这是因为Java忽略了int的溢出。
这可以通过执行以下代码来演示:
int count = 0;
int inSampleSize = 1;
while (inSampleSize != 0) {
count++;
inSampleSize *= 2;
}此循环将在inSampleSize的值为零时终止,此时count为32。
那么,剩下的问题是,上面的代码在什么情况下执行while循环的32次迭代?答案是,当reqWidth和reqHeight都小于1时。
因此,例如,如果您调用:
calculateInSampleSize(options, 0, 0);您将看到您所描述的问题。
如果reqWidth或reqHeight为零,则加载位图可能根本没有意义,因为它将不可见。但是,您可能正在使用View.getWidth()和View.getHeight()获取宽度和高度,并且在某些情况下,在视图布局之前调用它们还为时过早,此时这些方法可能会返回0。显然,最后这一点只是个猜测,如果不看更多代码就不可能知道,但我相信,如果您将reqWidth和reqHeight添加到日志中,当发生这种情况时,您会看到它们小于1。
发布于 2016-01-19 22:50:56
因为height和halfHeight是整型的,所以您会遇到这个异常。
final int halfHeight = height / 2;如果height =1,这里的halfHeight将为0。当你呼叫的时候
halfHeight / inSampleSize因为halfHeight是0,所以你会得到ArithmeticException。
Solution:在开始操作之前,特别是在进行除法运算时,将所有度量转换为double或BigDecimal。
https://stackoverflow.com/questions/28997474
复制相似问题