您的位置:首页 > 移动开发 > Android开发

Android RelativeLayout.mesure()时出现NullPointerException异常

2017-07-11 10:01 453 查看
        先说说怎么发现的这个问题,项目中使用的是百度地图,在搞百度地图的时候,需要在地图上添加Marker(标注覆盖物),自定义一个布局文件,根Layout为RelativeLayout,然后将自定义的布局文件转换成Bitmap,然后转换成BitmapDescriptor(BitmapDescriptor是百度地图的,这里不是重点),之后添加标注,显示在地图上。做完之后运行测试,没有问题,换一个手机测试,也没有问题,再换一个手机,同样没问题。好了,提交代码。原本以为这点小事就做完了,结果同事更新下来代码之后运行,程序崩溃了,竟然崩溃了......崩溃了.......,我立马拿他手机测试了一下,确实是崩溃了,这尼玛也是醉了。看了一下错误日志,竟然是空指针异常


异常信息:



定位到代码:

private BitmapDescriptor changeToBitmap(View view) {

view.setDrawingCacheEnabled(true);

view.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0,
view.getMeasuredWidth(),
view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap cacheBitmap = view.getDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
BitmapDescriptor icon = BitmapDescriptorFactory.fromBitmap(bitmap);
return icon;
}        发现是view.measure这一行报错,在我测试的其他3部手机上都没问题,结果在这个手机上出问题了,当时第一想法就是android版本的问题,看一下版本,我测试过的3部手机版本分别是21、22、23(即5.0.1、5.1、6.0)没有问题,有问题的那部手机API为17(即android4.2版本),怎么会这样呢,难道view.measure方法在不同的版本源码不同???在线看了一下android源码,尼玛,还真有问题。
首先看官方这么一段话:



大概翻译一下就是:

在平台版本17(包含17)或更低,RelativeLayout会受测量错误的影响导致子视图测量不正确,在RelativeLayout的控件使用在含有scrolling的时候,该含有scrolling的控件中计算空间大小,没有使用MeasureSpec mode UNSPECIFIED的布局方式在RelativeLayout。自定义的控件则会尽可能的使用AT_MOST 来替换对齐方式。

这种行为已经保存应用程序设置Android的targetSdkVersion =“17”或以上的清单的使用SDK标签的兼容性。针对SDK 18版或更新版的应用程序将获得正确的行为。

说人话就是RelativeLayout在API17及以下版本使用measure方法是有BUG的,会出现空指针异常,18及以上是没有问题的。

再看一下RelativeLayout的onMeasure源码(既然官方说18(即android4.3)修复了,那就对比之前的看一下有什么不同吧):



        左边是18(android4.3),右边是19(android4.4),可以看到,在4.4版本中增加了非空判断,之前版本没有这个。(说到这我又想吐槽了,刚刚官方明明说18就已经解决这个BUG了,为什么在19上才看到这个非空判断,也是无语。。。)

       好了,啰啰嗦嗦那么多,总之就是:

RelativeLayout.measure方法在android4.4版本之后没有空指针异常这个BUG,但之前版本会抛出空指针异常。

解决方法:

在RelativeLayout布局外面再嵌套一层FrameLayout或者LinearLayout即可。

相信会有好多像我一样不知道这个坑的猿猿们,希望能帮到你们。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐