android activity四种启动模式介绍及应用场景以及实例演示

在开发中会涉及到多个activity之间的跳转,或者其他应用可复用的activity,例如我们可能希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。就要为Activity配置特定的加载模式,而不是使用默认的加载模式

一、模式介绍

  1. standard模式
    这是默认模式,每次激活activity时都会创建新的实例,并放入任务栈中。
  2. singleTop模式
    如果在栈中已经有该Activity的实例,并且是在栈顶就复用该实例(会调用实例的 onNewIntent() )。如果已在栈中不在栈顶,会重新创建该实例放入栈中。
  3. singleTask模式
    如果在栈中已经有该Activity的实例,就复用该实例(会调用实例的 onNewIntent() )。复用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。
  4. singleInstance模式
    在一个新任务栈中创建该Activity的实例,一个栈中activity唯一,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。

设置启动模式的位置在 AndroidManifest.xml 文件中 Activity 元素的 android:launchMode 属性。

二、实例演示

1.standard模式代码演示
这种模式不用在配置android:launchMode属性,默认即可。
创建一个FirstActivity,演示一下标准的启动模式,代码如下:

public class FirstActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        TextView tv = (TextView) findViewById(R.id.tv);
        //展示当前activity实例序列号
        tv.setText(this.toString());

        Button bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(FirstActivity.this,FirstActivity.class));
            }
        });
    }
}

点击Button用于跳转到下一个FirstActivity界面,然后我们连续三次点击按钮,将会出现下面的现象:

这里写图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ineBo8g4-1616410943455)(https://img-blog.csdn.net/20170310155553980?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUm9ja3lIdWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZFq5wXpy-1616410943456)(https://img-blog.csdn.net/20170310155606137?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUm9ja3lIdWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

我们注意到同样是FirstActivity的实例,但每次点击后实例号发生了变化,我们持续后退两次,才能退回到第一个FirstActivity。standard模式的原理如下图所示:
这里写图片描述

如图所示,每次跳转系统都会在Task中生成一个新的FirstActivity实例,并且放于栈顶,按下后退键时才能看到原来的实例。
这种默认模式,不管有没有已存在的实例,都会生成新的实例。
简单点理解:standard启动模式Activity栈从栈底到栈顶顺序为A1 -> B -> C -> A2…。(其中A、B、C等都表示不同的Activity实例,A1、A2则表示属于具有同一Activity类的不同实例)
2.singleTop模式
我们在上面的基础为指定属性android:launchMode=“singleTop”,系统会按照singleTop启动模式处理跳转行为。我们重复几个动作,会出现下面的现象:
第一次出现的结果
点击第二次
这里写图片描述
我们发现三次FirstActivity的实例号没有变化,说明使用的同一个FirstActivity实例,如果按一下后退键,程序会立即退出,说明当前栈结构中只有一个Activity实例。原理如图所示:
这里写图片描述

上图所示,跳转时系统会先在栈结构中查找是否存在FirstActivity的实例,如果有会直接使用,不会生成新的实例。
上面我们演示了栈中只有一个Activity,如果多个呢?如果不是在栈顶如何?我们下面通过在同一个示例再演示一下。
再新建一个Activity命名为SecondActivity,代码如下:

public class SecondActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        TextView textView = (TextView) findViewById(R.id.tv);
        textView.setText(this.toString());
        Button button = (Button) findViewById(R.id.bt);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });
    }
}

将FirstActivity跳转代码改为跳转到SecondActivity,点击按钮如图所示结果:
这里写图片描述
这里写图片描述
这里写图片描述
我们发现再从SecondActivity跳转到FirstAcitivity后实例值发生了改变,说明生成了新的实例。原理如下图:
这里写图片描述
singleTop启动模式如果发现实例位于栈顶,会重复使用,不会生成新的实例。
简单点理解,singleTop即表示当前Activity栈中“栈顶唯一”,Activity跳转顺序或standard模式下栈结构如果为:A -> B -> C -> D1 -> D2,则singleTop启动模式为:A -> B -> C -> D1(此时回调D1的onNewIntent()…)。

3.singleTask
在上面的基础上我们修改FirstActivity的属性android:launchMode=“singleTask”。演示的结果如下:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
我们注意到,在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。singleTask模式的原理图如下图所示:
这里写图片描述

在图中的下半部分是SecondActivity跳转到FirstActivity后的栈结构变化的结果,我们注意到,SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivity时,SecondActivity实例都被迫出栈,下次等FirstActivity跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。
这就是singleTask模式,如果发现所在Activity栈中有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
简单点理解,singleTask表示当前Activity栈中“实例唯一”,Activity跳转顺序或standard模式下栈结构如果为:A -> B1 -> C -> D -> B2,则singleTask启动模式为:A -> B1(此时回调onNewIntent()…)

4.singleInstance
这种启动模式特殊在它会启动一个新的栈结构,将Activity放置于新的栈结构中,并保证不再有其他的Activity实例进入。
我们修改FirstActivity的launchMode=“standard”,SecondActivity的launchMode=“singleInstance”,由于涉及到了多个栈结构,我们需要在每个Activity中显示当前栈结构的id,所以我们为每个Activity添加如下代码:

  TextView tvTask = (TextView) findViewById(R.id.tv_taskid);
        tvTask.setText("current task id:"+this.getTaskId());

我们演示一下流程,如下所示:
这里写图片描述
这里写图片描述

我们发现这两个Activity实例分别被放置在不同的栈结构中,关于singleInstance的原理图如下:

这里写图片描述

我们看到从FirstActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到FirstActivity,这个时候系统会在原始栈结构中生成一个FirstActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?第一次按Back键首先是在当前Activity栈中将栈顶元素出栈,然后显示当前Activity栈中下一个Activity栈,然后再按下Back键,不是回到手机桌面,而是回到另一个Activity栈中的SecondActivityInstance,在于“最近栈”,只要此栈位于上次Home操作之后,就会先显示它。
如果我们修改FirstActivity的launchMode值为singleTop、singleTask、singleInstance中的任意一个,流程将会如图所示:
这里写图片描述

**简单点理解,singleInstance所标识的Activity,当被启动时,系统会首先判断系统其他栈中是否已经存在此Activity实例,有则直接使用,并且其所在的Activity栈理论上只有它一个Activity元素。所以启动它的Activity与它并不在一个task中,所以才需要特别注意Back的问题。一般表示为:task1 A -> task2 B。
singleInstance表示该Activity在系统范围内“实例唯一”。由此我们发现,singInstance和singleTask主要区别在与系统范围内的“实例唯一”还是当前Activity栈“实例唯一”。
**

三,应用场景

singleTop适合接收通知启动的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。从外界可能多次跳转到一个界面

singleTask适合作为程序入口点。例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。之前打开过的页面,打开之前的页面就ok,不再新建

singleInstance适合需要与程序分离开的页面。例如闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。某个应用中用到了google地图,当退出该应用的时候,进入google地图,还是刚才的界面。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值