设置Intent.FLAG_ACTIVITY_NEW_TASK和Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED对Activity Stack的影响

这是一个小区广播问题引发的对Intent.FLAG_ACTIVITY_NEW_TASK和Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的思考

现把该问题的解决过程和分析记录如下:

一、问题描述-删除未读广播消息后,进入短信-menu小区广播还会弹出广播提示框

预制条件 手机有一条未读广播消息

测试步骤:

1.进入设置-更多-小区广播 删除此条消息

2.进入短信-Menu-小区广播

预期结果:不会弹出广播消息框

实际结果:弹出了广播消息框

二、问题原因分析:

       按照测试流程,在收到一条消息后,不点确定,直接点击home键退出,此时显示消息的activity并没有关闭,只是推到了后台。之后在setting中删除消息。此时也不会对显示 消息的activity产生影响,这个activity仍然存在。之后通过MMS的设置打开cell broadcast时,是通过startactivity()方法打开的,此时给intent设置了flag为0x10200000,导致将之前显示消息的activity被重新从Activity Stack中调取出来,而不是打开消息列表界面,所以我们看到的是之前被推到后台的Activity,Activity中有未读消息提示框。

三、修改方案

       将MMS应用中的H我BaseActivity类中的沟通CellBroadcast()方法中的cellBroadcaseIntent.setFlag(0x10200000);删掉,即startActivity()不设置flag参数0x10200000。gotoCellBroadCast()完整方法如下,

public static void gotoCellBroadCast(Context activity){
    Intent cellBroadcastIntent = new Intent(Intent.ACTION_MAIN);
    cellBroadcastIntent.setComponent(new ComponentName("com.android.cellbroadcastreceiver","com.android.cellbroadcastreceiver.ui.CellBroadcastActivity"));
    cellBroadcastIntent.setFlags(0x10200000);
    try {
        activity.startActivity(cellBroadcastIntent);
    }catch (ActivityNotFoundException ignored){
        Log.e(TAG,"ActivityNotFoundException for CellBroadcastActivity");
    }catch (SecurityException e){
        Log.e(TAG,"SecurityException for CellBroadcastActivity");
    }
}

四、0x10200000数值解释

0x10200000表示属性为Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,其中Intent.FLAG_ACTIVITY_NEW_TASK和Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED是定义在Intent.java中的常量

public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000;

FLAG_ACTIVITY_NEW_TASK 和FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 的谷歌官方解释

来源:

https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK

   https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED





FLAG_ACTIVITY_NEW_TASK

        设置此状态,记住以下原则,首先会查找是否存在和被启动的Activity具有相同的亲和性的任务栈,如果有,刚直接把这个栈整体移动到前台,并保持栈中的状态不变,即栈中的activity顺序不变,如果没有,则新建一个栈来存放被启动的activity

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

       如果设置该属性,这个activity将在一个新的task中启动或者或者被带到一个已经存在的task的顶部,这时这个activity将会作为这个task的首个页面加载。将会导致与这个应用具有相同亲和力的task处于一个合适的状态(移动activity到这个task或者从中移出),或者简单的重置这个task到它的初始状态

设置0x10200000的作用

如果目标程序已经启动过,但是隐藏了,设置0x10200000之后,及时之前打开了,现在打开的话就直接跳到之前打开的页面

五、修改前后Activity Stack变化

修改前




修改后



`Intent.FLAG_ACTIVITY_NEW_TASK` 和 `Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED` 是两个标志位,用于指示启动 Activity 的行为。它们通常与 `Intent` 的 `setFlags()` 方法一起使用。 `Intent.FLAG_ACTIVITY_NEW_TASK` 的作用是告诉系统创建一个新的任务栈来启动目标 Activity,而不是在当前任务栈中启动它。如果目标 Activity 已经在系统中运行,它将被移动到前台,并成为新任务栈中的根 Activity。这个标志位通常用于启动一个独立的 Activity,例如启动一个全新的应用程序。 `Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED` 的作用是告诉系统如果目标 Activity 已经在前台,并且它所在的任务栈已经在后台,那么将该任务栈移到前台,并清空栈中所有 Activity 的状态。如果目标 Activity 不在前台,或者它所在的任务栈已经在前台,那么这个标志位不起作用。这个标志位通常用于判断用户是否在使用当前任务栈中的 Activity,如果不是,那么就将该任务栈移到前台,并清空栈中的状态。 这两个标志位通常一起使用,以确保目标 Activity 能够以正确的方式启动。例如,如果你想要启动一个新的 Activity,并将它放在一个新的任务栈中,你可以这样使用: ``` Intent intent = new Intent(this, TargetActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); ``` 在这个示例中,我们使用 `Intent.FLAG_ACTIVITY_NEW_TASK` 标志位创建一个新的任务栈,并使用 `Intent.FLAG_ACTIVITY_CLEAR_TASK` 标志位清空该任务栈中的所有 Activity。这样,我们就能够启动一个新的 Activity,并确保它位于一个独立的任务栈中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值