那些我们解过的bug之对话框锁屏解锁后消失的问题

本文通过分析log和代码,解决了客户报告的SAT消息对话框在熄屏后再亮屏时消失的问题。通过去除特定Intent标志,确保了对话框始终显示。

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

这里写图片描述

问题描述

现在我负责哥伦比亚的一个订单项目,客户测出了一个bug:

When the handset receive a SAT message, and you turn off the screen, wait for few minutes, turn on the screen, you can see that the SAT message disappears, after few minutes the SAT message appear again.

Please, when the user turn off the screen and turn on, the SAT message need to show in the screen normally, follow the video and log

客户说收到SAT信息后,会弹出一个确认对话框,然后手动熄灭屏幕,等待几分钟,然后再点亮屏幕,发现SAT信息确认对话框消失了,过几分钟确认对话框又弹出来了。

客户希望是一直都有显示出来。

解决问题的瓶颈

此问题的关键是国内的网络不能复现

这非常要命的,对于此种问题,只有二个办法,一是看代码,二是分析log。

解决问题

第一步,对比机测试

我要客户帮忙用同平台,同版本的对比机测试,看看是不是和我们是同样的现象,悲剧的是客户回复没有对比机,如果一定要的话,要向领导申请去市场购买。好吧,算我没说。

第二步,代码分析

我们找到与之相关的代码—StkDialogActivity.java
此对话框是一个Activity:

public class StkDialogActivity extends Activity implements View.OnClickListener {
    ................
    ................
    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        ................

    }


    @Override
    public void onResume() {
        super.onResume();
        ................
    }

    @Override
    public void onPause() {
        super.onPause();
        ................

    }

    @Override
    protected void onStart() {
        super.onStart();
        ................
    }

    @Override
    public void onStop() {
        super.onStop();
       ................
    }
        @Override
    public void onDestroy() {
        super.onDestroy();
        ................

    }

       ................
}

第三步,分析log

我在activity的每个生命周期加上log,出了一个临时调试userdebug版本,请客户帮忙提供log。

抓log的命令:

adb logcat -v time -b radio -b main -b system >adblog

客户提供了Log,大概2M,我们分析此log:

对话框activity的关键生命周期的log:
oncreate:

12-10 22:52:59.286 D/CAT     ( 3207): StkDialogActivity: hexiaoming: StkDialogActivity--onCreate

onStart:

12-10 22:52:59.314 D/CAT     ( 3207): StkDialogActivity: wenming: StkDialogActivity onStart() 

onResume:

12-10 22:52:59.316 D/CAT     ( 3207): StkDialogActivity: wenming: StkDialogActivity onResume()

onPause:

12-10 22:53:11.317 D/CAT     ( 3207): StkDialogActivity: wenming: StkDialogActivity onPause() 

onStop:

12-10 22:53:11.346 D/CAT     ( 3207): StkDialogActivity: wenming: StkDialogActivity onStop() 

onDestroy:

下面这个log是调用锁屏界面:
I/Timeline( 5250): Timeline: Activity_launch_request id:com.celltick.lockscreen time:1663498


这个Log是显示锁屏界面
I/am_create_activity(  776): [0,490226615,54,com.celltick.lockscreen/.LockerActivity,NULL,NULL,NULL,278986752]


这个log是最关键的,关闭对话框确认界面,原因是:no-history
I/am_finish_activity(  776): [0,666614507,53,com.android.stk/.StkDialogActivity,no-history]

这个log是关闭对话框确认界面
I/am_destroy_activity(  776): [0,666614507,53,com.android.stk/.StkDialogActivity,finish-imm]

这个log是对话框确认界面的onDestroy生命周期
D/CAT     ( 3207): StkDialogActivity: wenmings: StkDialogActivity onDestroy() 

其实,至此,我们已经知道了,对话框确认界面关闭的原因是no-history。

第四步:修改代码

我们再回到源码中,发现只有在启动对话框确认界面时,有这样的一段代码:

        | Intent.FLAG_ACTIVITY_CLEAR_TOP
        | Intent.FLAG_ACTIVITY_SINGLE_TOP
        | Intent.FLAG_ACTIVITY_NO_HISTORY

StkAppService.java

Intent newIntent = new Intent(sInstance, StkDialogActivity.class);
if (newIntent != null) {
    newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
        | Intent.FLAG_ACTIVITY_CLEAR_TOP
        | Intent.FLAG_ACTIVITY_SINGLE_TOP
        | Intent.FLAG_ACTIVITY_NO_HISTORY
        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
        | getFlagActivityNoUserAction(InitiatedByUserAction.unknown));
     newIntent.putExtra(SLOT_ID, mCurrentSlotId);
     newIntent.putExtra("TEXT", mCurrentCmd.geTextMessage());

startActivity(newIntent);

问题找到了,我们如下修改一下代码:

Intent newIntent = new Intent(sInstance, StkDialogActivity.class);
if (newIntent != null) {
    newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
//        | Intent.FLAG_ACTIVITY_CLEAR_TOP
//      | Intent.FLAG_ACTIVITY_SINGLE_TOP
//      | Intent.FLAG_ACTIVITY_NO_HISTORY
        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
        | getFlagActivityNoUserAction(InitiatedByUserAction.unknown));
     newIntent.putExtra(SLOT_ID, mCurrentSlotId);
     newIntent.putExtra("TEXT", mCurrentCmd.geTextMessage());

startActivity(newIntent);

把这三个都注释掉,再编译一个临时版本给客户确认,客户回复说OK了,问题解决。

总结

第一,log的分析:
此问题的解决,因为我们不能重现此问题,只能完全是依靠log信息来定位问题的原因,再找到对应的代码修改。
log是不会说谎的,她会把事实的真相原原本本的记录下来,关键是我们要会看明白她,读懂她。

第二:Intent的这几个FLAG的意义

建议可以先看一下这篇文章:
Activity启动模式 及 Intent Flags 与 栈 的关联分析
http://blog.youkuaiyun.com/vipzjyno1/article/details/25463457

Intent.FLAG_ACTIVITY_CLEAR_TOP

这个FLAG就相当于启动模式中的SingleTask,这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。例如:原来栈中的结构是A B C D ,从D中跳转到B,栈中的结构就变为了A B了。(这个方法可以用来关闭多个Activity,之后的一篇博文里面会提到)

Intent.FLAG_ACTIVITY_SINGLE_TOP

这个FLAG就相当于启动模式中的singletop,例如:原来栈中结构是A B C D,在D中启动D,栈中的情况还是A,B,C,D。

Intent.FLAG_ACTIVITY_NO_HISTORY

顾名思义,此activity没有历史,一旦不可见就立刻关闭。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hfreeman2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值