Android Activity管理类NoSuchElementException的bug总结

本文作者通过友盟bug统计发现一个Android应用在使用Activity管理类时偶尔出现NoSuchElementException的问题。经过分析,发现在app启动时,引导页未入栈,用户快速点击物理返回键会触发该错误。解决方案是对相关逻辑进行修改,避免在栈中无元素时调用lastElement()方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请标明出处

http://blog.csdn.net/mohan6/article/details/76988369

本文作者:【默寒的博客】


前言:项目集成了友盟的bug统计,于是乎发现了一个抓狂的bug。搞了一上午才搞清楚这个bug。如果你用的activity的管理类,并且出现NoSuchElementException,请自行检查是否和我的情况一样。如果命中,一起抱头痛哭吧。

一.友盟bug统计呈现的:


表象:偶发的,不是偶发的测试一定测出来,不至于上线后以后这样的bug,而且平时也没遇到这个bug。

二.bug在自己测试机上出现,并恰巧被我看到!并且这几天友盟的邮件隔三差五就会提醒有这个bug,这个bug不能忽视了!

bug分析:

因为一直认为是偶发的bug,并且不能重现,于是乎无从下手。前期想try……catch掉,没准是哪里发神经出错的。但是这样治标不治本,没办法啊,总不能让程序崩掉,这样跟难看。

那就分析一下吧,没准能找到根源,抱着试试的态度。根据之前发生bug的时候我定位的位置我找到了这里:


然后从这里入手,点进去是自己写的activity的管理页,额……lz接手这个项目的时候就已经有这个管理类。那么看一下这个finishActivty吧。


activityStack是new Stack,这个stack是extends Vector,而这个lastElement正是Vector的方法。

public synchronized E lastElement() {
  throw new RuntimeException("Stub!");
}
我脑袋大开,既然是偶现的bug,那么会不会是线程安全问题。Vector是线程安全的,CountDownTimer这个类的onFinish()是主线程啊,我这样反复操作也不会出现线程安全问题吧。

然后就又回到了起点,还好try....catch吧,那跑一下吧,没bug提交代码。就在这时,哇,我又给点崩了,再点。。。。崩!再点。。。。又崩。激动ing!!!!!!我无意中重现了bug,去它的try....catch,我找到根源了!

三、正解来了!!!!

app刚刚启动,引导页还未入栈,我快速点物理返回键!恩!就是这样!bug重现了!

看看我捕捉返回键做了什么吧


我再点物理返回键时,调了这个该死的finishingActivity()方法!

此时栈中无元素!lastElement()???哪里有啊,必须报NoSuchElementException!至此这个bug并不是偶现的!它就是bug。那么为什么平时不会发现呢,因为引导页3秒--》首页,一般人在这3秒钟内很少有点物理返回键的,于是就没发现这个bug,关键测试竟然也没测出来!估计出现的时候大概测试也觉得是幻觉,无法重现就没法找开发说理吧。我重新还原到有bug的情况,打印了一下

 LogUtil.e("ym",activityStack.size()+"size");
出现bug的时候,size真的是0!!!!

解决方法:

/**
   * 结束当前Activity(堆栈中最后一个压入的)
   */
  public void finishActivity() {
    //2017.8.9 解决友盟抓取的bug ym start
    // java.util.NoSuchElementException,at java.util.Vector.lastElement(Vector.java:621),
    // at com.carpass.common.util.ActivityManager.finishActivity(ActivityManager.java:62),
    // bug定位:ACT_Guide->首页,关自己的时候报错的。
    // 原因:ACT中onKeyDown监听物理返回键中调用了 ActivityManager.getAppManager().finishActivity();
    //bug重现:启动ACT_Guide页面时,快速点击物理返回键,此时  LogUtil.e("ym",activityStack.size()+"size");size=0!!!
//    Activity activity = activityStack.lastElement();
//    finishActivity(activity);
    if (activityStack == null || activityStack.size() == 0) {
      return;
    }
      Activity activity = activityStack.lastElement();
      finishActivity(activity);
    //2017.8.9 解决友盟抓取的bug ym end
  }

到此,成功灭掉这个bug!生气折磨我许久!终于成功消灭!大笑



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值