前言

对app的线上bug的收集(友盟、云捕等)有时会得到这样的异常堆栈信息:没有一行代码是有关自身程序代码的。这使得对bug的解决无从下手,根据经验,内存不足OOM,Dialog关闭,ListView等相关代码很容易引起这类错误。下面总结下BaseAdapter.getView崩溃bug,然后给出如何编写代码来方便以后对它的定位。

BaseAdapter.getView

如果getView方法返回null,那么对应的ListView在显示时就直接触发NullPointerException异常。但是无论是哪个界面的哪个ListView发生了这个错误,对应的异常信息总是这样的:

  1. E/AndroidRuntime: FATAL EXCEPTION: main
  2. Process: com.example.hxw.myapplication, PID: 1662
  3. java.lang.NullPointerException
  4. at android.widget.AbsListView.obtainView(AbsListView.java:2274)
  5. at android.widget.ListView.makeAndAddView(ListView.java:1790)
  6. at android.widget.ListView.fillDown(ListView.java:691)
  7. at android.widget.ListView.fillFromTop(ListView.java:752)
  8. at android.widget.ListView.layoutChildren(ListView.java:1630)
  9. at android.widget.AbsListView.onLayout(AbsListView.java:2087)
  10. at android.view.View.layout(View.java:14817)
  11. at android.view.ViewGroup.layout(ViewGroup.java:4631)
  12. at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
  13. at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
  14. at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
  15. at android.view.View.layout(View.java:14817)
  16. at android.view.ViewGroup.layout(ViewGroup.java:4631)
  17. at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
  18. at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
  19. at android.view.View.layout(View.java:14817)
  20. at android.view.ViewGroup.layout(ViewGroup.java:4631)
  21. at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
  22. at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
  23. at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
  24. at android.view.View.layout(View.java:14817)
  25. at android.view.ViewGroup.layout(ViewGroup.java:4631)
  26. at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
  27. at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
  28. at android.view.View.layout(View.java:14817)
  29. at android.view.ViewGroup.layout(ViewGroup.java:4631)
  30. at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1983)
  31. at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1740)
  32. at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
  33. at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
  34. at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
  35. at android.view.Choreographer.doCallbacks(Choreographer.java:574)
  36. at android.view.Choreographer.doFrame(Choreographer.java:544)
  37. at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
  38. at android.os.Handler.handleCallback(Handler.java:733)
  39. at android.os.Handler.dispatchMessage(Handler.java:95)
  40. at android.os.Looper.loop(Looper.java:136)
  41. at android.app.ActivityThread.main(ActivityThread.java:5001)
  42. at java.lang.reflect.Method.invokeNative(Native Method)
  43. at java.lang.reflect.Method.invoke(Method.java:515)
  44. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
  45. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
  46. at dalvik.system.NativeStart.main(Native Method)

可以看到,整个异常信息提供的堆栈是不含任何与自己代码相关的调用信息的。

实际上,错误是因为getView返回null引起的,但是从上面的信息无法定位到到底哪个Adapter发生问题。

如果可以收集到用户是在哪个页面发生崩溃那么问题的定位会准确许多,但是,如果自己的Adapter需要返回好多种View(也就是getViewTypeCount的值,比如一个包含很多不同布局的对话列表),那么你还是需要仔细分析代码来找到具体哪个View的生成逻辑出了问题。

更多时候,除了得到以上的错误堆栈,对于真正的bug再无更多信息。实际上是无法判断出具体出问题的Adapter的。解决办法只能从根源上进行:

在我们编写getView方法时,对最终返回的参数自己进行非空判断,当针对不同position处的getItemViewType得到的View对象为null时,可以自己抛出一个NullPointerException,而不是等getView的调用者(框架API)来抛出上面给出的“没用”的信息。

也可以针对null的情况返回一个有用的信息给用户,而不是让程序崩溃。

  1. // 在自己的Adapter子类中
  2. @Override
  3. public View getView(int position, View convertView, ViewGroup parent) {
  4. return buildView(position, convertView, parent);
  5. }
  6. private View buildView(int position, View convertView, ViewGroup parent) {
  7. // ... 这里是根据getItemViewType生成不同View的逻辑,将View对象存储在convertView
  8. if (convertView == null) {
  9. // throw 一个Exception,包含position,getItemViewType的数据,方便定位
  10. // 或者生成一个默认的View,提供给用户有用的信息——如果的确不至于让app crash的话
  11. }
  12. return convertView;
  13. }

通过上面的方式,如果自己的getView的逻辑返回了null的话,就可以根据堆栈直接定位到错误代码的位置。

注意:getView返回null从java语法上是没问题的,虽然根据约定,它返回null肯定会引发空指针异常——但是这是对调用getView的方法而言。根据堆栈,在页面的ListView显示其childView时,如果getView返回null,android.widget.AbsListView.obtainView方法就抛出异常。堆栈信息只跟踪到LisView,而不会指向具体的Adapter。

(本文使用Atom编写)

[异常特工]android常见bug跟踪的更多相关文章

  1. android 常见死机问题--log分析

    http://blog.csdn.net/fangchongbory/article/details/7645815         android 常见死机问题--log分析============ ...

  2. 常见bug解析-移动端

    手机测试常见bug解析 1.测试时遇到“手机无响应”? 有以下几个原因: a.手机内存不足 b.android进程之间死锁引起的(就是两个进程之间) c.手机的CPU运行高引起的 可以查看手机的崩溃日 ...

  3. Android自动化压力测试之Monkey Test Android常见的错误类型及黑白名单的使用方法(四)

    Android常见的错误类型有两种 1.ANR类型 1)在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸) 2)BroadcastReceiver在10秒内没有执行完毕 2.Crash类型 1)异 ...

  4. Android 常见工具类封装

    1,MD5工具类: public class MD5Util { public final static String MD5(String s) { char hexDigits[] = { '0' ...

  5. Android常见开源解决方案

    原文:http://m.pstatp.com/group/6348269082899497218/?iid=6036708044&app=news_article&tt_from=mo ...

  6. Android的BUG(三) - 广为人知的诟病:频繁重启问题

    使用过Android的同学,尤其是用过山寨pad,应该对Android的重启问题印象深刻吧.Android由于其设计的复杂性,可能会使得系统在不经意时陷入异常状态,因此Android设计了一套看门狗机 ...

  7. Android常见漏洞

    Android常见漏洞 漏洞名称: Log敏感信息泄露 漏洞描述: 程序运行期间打印了用户的敏感信息,造成泄露 修改建议: 建议禁止隐私信息的log 漏洞名称: web https校验错误忽略漏洞 漏 ...

  8. 如何在本地搭建一个Android应用crashing跟踪系统-ACRA

    https://github.com/bboyfeiyu/android-tech-frontier/tree/master/others/%E5%A6%82%E4%BD%95%E5%9C%A8%E6 ...

  9. Android常见面试笔试题目

    Android常见面试笔试题目 1.在多线程编程这块,我们经常要使用Handler,Thread和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢? 答:可以处理消息循环的线程,他是一个拥 ...

随机推荐

  1. 学习AOP之透过Spring的Ioc理解Advisor

    花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...

  2. 前端常用的WindowsCMD命令

    前面的话   在网上找了一些关于命令提示符CMD的资料,但是很多资料都是把所有的功能罗列出来,大部分都不会用到.所以,自己把常用的CMD命令总结如下,方便查阅 操作类 help 列出所有支持的指令及说 ...

  3. .NET Core的日志[4]:将日志写入EventLog

    面向Windows的编程人员应该不会对Event Log感到陌生,以至于很多人提到日志,首先想到的就是EventLog.EventLog不仅仅记录了Windows系统自身针对各种事件的日志,我们的应用 ...

  4. ASP.NET Core 中文文档 第五章 测试(5.2)集成测试

    原文: Integration Testing 作者: Steve Smith 翻译: 王健 校对: 孟帅洋(书缘) 集成测试确保应用程序的组件组装在一起时正常工作. ASP.NET Core支持使用 ...

  5. javascript动画系列第二篇——磁性吸附

    × 目录 [1]范围限定 [2]拖拽范围 [3]磁性吸附 前面的话 上一篇,我们介绍了元素拖拽的实现.但在实际应用中,常常需要为拖拽的元素限定范围.而通过限定范围,再增加一些辅助的措施,就可以实现磁性 ...

  6. cesium自定义气泡窗口infoWindow

    一.自定义气泡窗口与cesium默认窗口效果对比: 1.cesium点击弹出气泡窗口显示的位置固定在地图的右上角,默认效果: 2.对于习惯arcgis或者openlayer气泡窗口样式的giser来说 ...

  7. Linux字符设备驱动框架

    字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l ...

  8. 鱼眼模式(Fisheye projection)的软件实现

    简单实现 鱼眼模式(Fisheye)和普通的透视投影(Perspective projection),一个很大的区别就是鱼眼的投影算法是非线性的(non-linear),实际照相机的情况是在镜头外面包 ...

  9. 创建maven项目(cmd 命令)

    2016五月 22 原 创建maven项目(cmd 命令) 分类:maven (994) (0) 1.普通方式创建 1)进入cmd窗口执行 mvn archetype:generate 2) 光标停止 ...

  10. 闭区间套定理(Nested intervals theorem)

    ① ②这里用到了极限与不等关系 ③如果a≠b,那么便不会有$\lim _{n\rightarrow \infty }\left| I_n \right| =0$ ④如果还存在一点c在内,那么同样也不会 ...