介绍

上篇提到了Activity的任务,任务栈,以及启动模式。对这些概念有了了解以后,自己写一下例子来感受一下,就当作复习和加深印象了。如果对概念不熟悉的可以参考:深入理解Activity-任务,回退栈,启动模式。

standard(标准模式)

1、概念

前面我们已经提到过,这是系统默认的模式,我们如果不在AndroidManifest.xml的Activity中制定launchMode属性,默认就是这种模式,谁启动了该模式的activity,一个该activity的实例就会被放置到谁的任务栈中。

2、例子

这个例子很简单,我们新建一个名为FirstActivity的Activity,然后放一个Button,当点击Button的时候启动自己。并且在onCreate方法中log打印出当前任务的id,代码如下:

public class FirstActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Log.d("taskId", "taskId is :" + getTaskId());
} public void click(View view) {
Intent intent = new Intent(this, FirstActivity.class);
startActivity(intent);
} }

运行之后我们点击6次按钮,查看log信息如下:

10-20 12:35:54.380 1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

10-20 12:36:32.705 1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

10-20 12:36:40.389 1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

10-20 12:36:43.581 1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

10-20 12:36:44.885 1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

10-20 12:36:46.965 1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

可以看到taskId都为2,说明我们的FirstActivity实例都在一个任务栈中,这个任务栈中是否的确有6个实例呢,我们在终端输入命令:adb shell dumpsys activity,执行后会出现很多信息,具体看下图:



可以看到正在运行的Activity有6个FirstActivity,由于我用MainActivity作为入口,所以还有一个MainActivity。此时处于resume状态的也是FirstActivity。到这里标准模式相信大家已经熟悉得不能再熟悉了。

关于adb的配置可以参考在Mac上配置Android adb命令

singleTop(栈顶复用模式)

1、概念

如果一个activity已经存在于一个任务栈中,那么系统就不会创建一个该activity的新实例,而是使用栈顶的activity实例,并且调用该activity的onNewIntent()的方法。

2、例子

我们新建一个名为A、B、C、三个Activity,修改C的启动模式为singleTop,第一次启动顺序为A->B->C->C。第二次我们启动顺序为A->B->C->A->C,也在onCreate方法中log打印出当前任务的id。

在执行了A->B->C->C之后我又点击了两次即A->B->C->C->C->C,log信息输出如下:

10-20 13:18:18.381 12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :3

10-20 13:18:26.701 12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :3

10-20 13:18:29.565 12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :3

10-20 13:18:32.741 12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ onNewIntent execute

10-20 13:18:59.021 12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ onNewIntent execute

10-20 13:18:59.729 12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ onNewIntent execute

可以看到的确是执行了onNewIntent方法

此时我们执行adb shell dumpsys activity以后查看任务栈中的Activity信息:



很显然虽然我们点击了多次跳转CActivity,但是由于在栈顶,所以复用了。

接下来看第二种情况A->B->C->A->C的log信息:

10-20 13:25:24.733 15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4

10-20 13:25:31.229 15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4

10-20 13:25:32.261 15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4

10-20 13:25:34.181 15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4

10-20 13:25:35.733 15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4

完全没有调用onNewIntent方法。

那么执行命令adb shell dumpsys activity查看一下任务栈中的信息:

上面的信息说明了当不在栈顶的时候,依然会创建新的实例.

singleTask(栈内复用模式)

1、概念

如果一个activity存在于任务栈中,那么系统会使用该实例并且调用它的onNewIntent() 方法,这种模式下在一个任务中只能有一个实例。启动一个带有该模式的Activity,系统会寻找该Activity所需的任务栈,如果存在就寻找栈中有没有该Activity的实例,有就复用。没有就新建一个实例压入栈中。而如果没有Activity所需的任务栈,系统就会新建一个任务栈,然后新建一个实例压入栈中。

2、例子

我们在上面的例子上多新建出一个DActivity并设置其launchMode为singleTask,第一次启动顺序为:A->B->D->D,第二次我们启动顺序为:A->B->D->C->D。

当启动顺序为A->B->D->D的log和任务栈的信息如下:

log信息:

10-21 02:17:57.929 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :7

10-21 02:18:01.581 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :7

10-21 02:18:02.945 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :7

10-21 02:18:04.481 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ DActivity onNewIntent execute

10-21 02:18:05.389 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ DActivity onNewIntent execute

任务栈信息:

而当启动顺序为A->B->D->C->D的log和任务栈的信息如下:

log信息

10-21 02:21:04.629 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8

10-21 02:21:11.621 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8

10-21 02:21:13.213 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8

10-21 02:21:14.869 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8

10-21 02:21:17.189 5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ DActivity onNewIntent execute

任务栈信息:

很明显singleTop模式之要栈中存在,就就复用,调用onNewIntent方法。而对应于第二种情况,由于要复用栈中的D,所有必需先让C出栈。所有栈内由顶向下是D->B->A。当我们finish的时候就会直接到B了。

3、TaskAffinity

在singleTask种,该参数表示一个Activity所需要的任务栈的名字,默认情况所有的Activity所需的任务栈的名字为应用的包名。 我们在上面例子中的DActivity配置 android:taskAffinity=”com.example.yangqiangyu.launchmode2”。然然后启动A->B->D,log信息如下:

10-21 02:34:34.053 15657-15657/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :9

10-21 02:34:42.513 15657-15657/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :9

10-21 02:34:44.437 15657-15657/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :10

可以看到DActivity的taskId和之前的不一样,说明它在另外一个任务栈中.

singleInstance

这个模式除了拥有singleTask的所有特点外,在该模式下的activity实只能单独的在一个任务栈中。这里就不写例子测试了

例子源码下载

深入理解Activity -动手写实例来感受Activity的启动模式的更多相关文章

  1. 自己动手写ORM的感受

    之前看到奋斗前辈和时不我待前辈的自己动手写ORM系列博客,感觉讲解的通俗易懂,清晰透彻.作为一个菜鸟,闲来也想着自己写一个ORM,一来加深自己对 ORM的理解,以求对EF,NHibernate等ROM ...

  2. Android启动Activity的两种方式与四种启动模式

    1.在一个Activity中调用startActivity()方法 2.在一个Activity中调用startActivityRequest()方法. 重写onActivityResult方法,用来接 ...

  3. Android总结篇系列:Activity启动模式(lauchMode)

    本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址: http://blog.csdn.net/l ...

  4. 【转】Android总结篇系列:Activity启动模式(lauchMode)

    [转]Android总结篇系列:Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些 ...

  5. Activity启动模式(lauchMode)

    Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址 ...

  6. Android中Activity的四种启动模式

    要了解Android的启动模式先要了解一下Activity的管理方式: 1.Activity的管理机制 Android的管理主要是通过Activity栈来进行的.当一个Activity启动时,系统根据 ...

  7. Android零基础入门第77节:Activity任务栈和启动模式

    通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容. Android采用任务栈(Task)的方式来管理Activity的实例.当启动一个应用时,Android就会为之 ...

  8. Android开发之---Activity启动模式

    在Android开发中,启动一个新的activity我们可以使用startActivity或startActivityForResult,Android系统使用栈的方式来管理一个APP的页面显示与保存 ...

  9. android launchmode(四种启动模式)应用场景及实例

    模式介绍 [1] standard 模式 这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中. [2] singleTop 模式 如果在任务的栈顶正好存在该Activ ...

随机推荐

  1. Bill Gates说..

    世界不会在意你的自尊,人们看的只是你的成就.在你没有成就以前,切勿过分强调自尊.

  2. java攻城狮之路(Android篇)--与服务器交互

    一.图片查看器和网页源码查看器 在输入地址的是不能输入127.0.0.1 或者是 localhost.ScrollView :可以看成一个滚轴 可以去包裹很多的控件在里面 练习1(图片查看器): pa ...

  3. WWDC2015 结束.新一波更新以及bug即将来袭.

    WWDC结束.新一波更新以及bug即将来袭. HTTPS 将成为标准链接. http被报错. GamePlayKit 这是搞那样. 还有ReplayKit  那些什么录像分享什么的还有活路么? Mod ...

  4. Linux高级编程--07.进程间通信

    每个进程各自有不同的用户地址空间,进程之间要交换数据必须通过在内核中开辟缓冲区,从而实现数据共享. 管道 管道是一种最基本的IPC机制,由pipe函数创建: int pipe(int filedes[ ...

  5. 斜堆(一)之 C语言的实现

    概要 本章介绍斜堆.和以往一样,本文会先对斜堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现:实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可.若文 ...

  6. [python]pip常用命令(转载)

    用阿里云服务器,使用pip安装第三方库的时候卡的要死.所以我就想pip能不能安装本地的包. 找到了这篇博客: http://me.iblogc.com/2015/01/01/pip%E5%B8%B8% ...

  7. Docker 定制容器镜像的2种方法

    一.需求 由于在测试环境中使用了docker官网的centos 镜像,但是该镜像里面默认没有安装ssh服务,在做测试时又需要开启ssh.所以上网也查了查资料.下面详细的纪录下.在centos 容器内安 ...

  8. 高级四则运算器—结对项目总结(193 &105)

    高级四则运算器—结对项目总结 为了将感想与项目经验体会分割一下,特在此新开一篇博文. 界面设计 啥都不说,先上图震慑一下... 上面的三个界面是我们本次结对项目的主界面,恩,我也觉得挺漂亮的!你问我界 ...

  9. 转贴:JavaScript实现Ajax请求简单示例

    转至:https://my.oschina.net/u/658145/blog/167651 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 ...

  10. 常用的android弹出对话框

    我们在平时做开发的时候,免不了会用到各种各样的对话框,相信有过其他平台开发经验的朋友都会知道,大部分的平台都只提供了几个最简单的实现,如果我们想实现自己特定需求的对话框,大家可能首先会想到,通过继承等 ...