我有一个JAVA(在Android上运行)方法,该方法偶尔会因除零而捕获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;
}
最佳答案
乍一看,如果您将一个数字初始化为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。