Android 启动模式梳理

4个启动模式

standard:标准模式,默认

栈内可以重复创建多个实例;
谁启动了这种模式的 Activity,新 Activity 就会运行在启动者所在的栈中

singleTop:栈顶复用

顾名思义,当Activity位于栈顶时不会开启新的Activity,会调用onNewIntent方法

singleTask:栈内复用模式

只要 Activity 在一个栈中有实例,多次启动此 Activity 都不会创建实例,也是直接调用 onNewIntent()。启动 singleTask 的 Activity 时,系统会先找有没有想要的任务栈,没有就新建个任务栈;有就看栈里有没有实例栈内有实例,就会把该 Activity 调到栈顶,同时 clearTop(之前在它前面的都被清除)

singleInstance:栈内唯一

一个Activity占用一个栈

Intent Flag 使用

//如果activity在task存在,拿到最顶端不会启动新的activity
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

//如果activity在task存在,将activity之上的所有activity结束到
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

//默认的跳转类型,将activity放到一个新的Task
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//如果Activty已运行到task,再次跳转不会再运行这个activity;
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
增加属性 “|”

如果需要向flag变量中增加某个FLAG,使用"|"运算符
flag |= XXX_FLAG
原因: 如果flag变量没有XXX_FLAG,则 | 完后flag对应的位为1,如果有XXX_FLAG,则 | 完后值不会变对应位还是1.

包含属性 “&”

如果需要判断flag变量中是否包含XXX_FLAG,使用"&"运算符
flag & XXX_FLAG != 0 或者 flag & XXX_FLAG = XXX_FLAG

原因: 如果flag变量里包含XXX_FLAG,则&完后flag变量对应的位为1,因为XXX_FLAG的定义保证了只有一位非0,其他位都为0,所以如果是包含的话&运算后值不为0,值为此XXX_FLAG的值,不包含的话值为0.

取消属性 “&~”

如果需要取消flag变量的XXX_FLAG, 使用 “&~”.
flag &= ~XXX_FLAG
原因: 先对XXX_FLAG进行取反 则XXX_FLAG原来非0的那一位变为0,则使用&运算符后flag变量非0的那一位变为0,则意味着flag变量不包含XXX_FLAG

多渠道处理

一般而言,换渠道打开app时我们想要的是带有CLEAR_TOP和NEW_TASK的启动,但是外部调用一般只有NEW_TASK,这也就导致我们在换渠道重新打开后有多首页的现象。

下图是我们希望的流程图,其中【扫一扫】是我们的目标软件
在这里插入图片描述

/**
     *      本方法处理外部渠道跳转引起的问题:
     *      1. 进入渠道变更时,只保留首页
     *      2. 渠道变更为桌面时,回到栈顶界面
     */
    private void intentFlagHandle() {
		//	本方法获取跳转过来的包名
        String appName = AppUtil.guessCallAppSource();
        Logger.d(TAG, " appName = " + appName);
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
            //  已有首页,换渠道时
            Logger.d(TAG, " ===  FLAG_ACTIVITY_BROUGHT_TO_FRONT  === ");
            if (TextUtils.isEmpty(appName)) {
                Logger.d(TAG, "===  FLAG_ACTIVITY_BROUGHT_TO_FRONT  ===  appName = " + appName);
                return;
            }
            //  如果是桌面,返回栈顶,不建新的首页
            if (appName.equals(PkgUtils.PKG_MIUI_HOME)) {
                Logger.d(TAG, "===  FLAG_ACTIVITY_BROUGHT_TO_FRONT  === 桌面跳入");
                finish();
                return;
            }
            //  如果是跳转渠道变更,则只保留首页,finish 所有除栈顶的 Activity
            Logger.d(TAG, "===  FLAG_ACTIVITY_BROUGHT_TO_FRONT  === 跳转渠道已变更");
            AppManager.INSTANCE.finishOutTop();
        } else {
            Logger.d(TAG, " ===  FLAG_ACTIVITY_BROUGHT_TO_FRONT  === 未拦截");
        }
    }

如此一来只要调用方使用了NEW_TASK(避免我们的Activity在别的app栈里)就可以了,进入我们的代码后全由自己处理

多渠道使用同一action问题

当多渠道使用相同action启动目标app时,若目标app已打开二级界面(即非有action的Activity)时会直接打开栈顶界面,现象与从最近任务启动类似。栈顶Activity的intent没有任何信息,对应action的Activity的intent有action和flag信息,但是不会走生命周期。所以建议此处要做下处理,一个渠道一个action,或者自己能接受现象。

最近任务栏

有时候 通过后台唤醒的 Activity 在结束任务后,不想让用户看到,这时候,需要自动的将它隐藏

通过代码隐藏

常规的关闭Activity 是 finish() ,但是如果想Activity关闭后不显示在最近任务中,则需要通过 finishAndRemoveTask() 来关闭

清单文件中配置

在需要隐藏的那个Activity 配置android:excludeFromRecents="true"即可

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值