深入理解Activity -动手写实例来感受Activity的启动模式
介绍
上篇提到了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的启动模式的更多相关文章
- 自己动手写ORM的感受
之前看到奋斗前辈和时不我待前辈的自己动手写ORM系列博客,感觉讲解的通俗易懂,清晰透彻.作为一个菜鸟,闲来也想着自己写一个ORM,一来加深自己对 ORM的理解,以求对EF,NHibernate等ROM ...
- Android启动Activity的两种方式与四种启动模式
1.在一个Activity中调用startActivity()方法 2.在一个Activity中调用startActivityRequest()方法. 重写onActivityResult方法,用来接 ...
- Android总结篇系列:Activity启动模式(lauchMode)
本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址: http://blog.csdn.net/l ...
- 【转】Android总结篇系列:Activity启动模式(lauchMode)
[转]Android总结篇系列:Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些 ...
- Activity启动模式(lauchMode)
Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址 ...
- Android中Activity的四种启动模式
要了解Android的启动模式先要了解一下Activity的管理方式: 1.Activity的管理机制 Android的管理主要是通过Activity栈来进行的.当一个Activity启动时,系统根据 ...
- Android零基础入门第77节:Activity任务栈和启动模式
通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容. Android采用任务栈(Task)的方式来管理Activity的实例.当启动一个应用时,Android就会为之 ...
- Android开发之---Activity启动模式
在Android开发中,启动一个新的activity我们可以使用startActivity或startActivityForResult,Android系统使用栈的方式来管理一个APP的页面显示与保存 ...
- android launchmode(四种启动模式)应用场景及实例
模式介绍 [1] standard 模式 这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中. [2] singleTop 模式 如果在任务的栈顶正好存在该Activ ...
随机推荐
- 修改oracle重做日志文件大小
创建3个新的日志组 SQL> ALTER DATABASE ADD LOGFILE GROUP 4 ('/u01/app/oracle/oradata/orcl/redo06.log') SIZ ...
- 使用Html5+C#+微信 开发移动端游戏详细教程 :(五)游戏图像的加载与操作
当我们进入游戏时,是不可能看到所有的图像的,很多图像都是随着游戏功能的打开而出现, 比如只有我打开了"宝石"菜单才会显示宝石的图像,如果是需要显示的时候才加载, 会对用户体验大打折 ...
- Guzzle – 构建 RESTful Web 服务的 PHP HTTP 框架
Guzzle 减轻了发送 HTTP 请求和创建 Web 服务客户端的痛苦.它包含建立一个强大的网络服务客户端的工具,包括:服务描述定义的输入和输出的 API,资源迭代器遍历分页资源,尽可能有效地发送大 ...
- 说说Web API数据格式化——Json
题外话 一同事离职了,我去上厕所的路上正巧碰到他办完离职手续出来,抱着他的全部家当,最值钱的可能就是那个两块钱的蓝色杯子和手中的雨伞了.在一块儿走向厕所的长长楼道里,我对他说:丫的,你是不是找到别的发 ...
- 【JavaScript回顾】闭包
什么是闭包? 闭包是指有权访问另一个 函数作用域中的变量的函数(也就是说,你这个函数用到的变量另外一个域的就算闭包) <script> function f1() { var age = ...
- 调试报“The source file is different from when the module was built.”问题的解决
It is related to the checksums which is used to ensure that you are stepping in matching source. You ...
- sencha combobox下拉框不用jsonstore,直接使用字符串数组做数据源
combobox下拉框的store除了可以选择一个jsonstore来加载数据,还可以直接使用符串Array做数据源. { xtype: 'combobox', fieldLabel: 'Label' ...
- 使用mvc3实现ajax跨域
ajax跨域一般两种方式 1:cors,2:jsonp, 1:cors jsonp是get形式,承载的信息量有限,所以信息量较大时CORS是不二选择 在请求消息头添头 Access-Control ...
- 数据库sqlserver2008登陆名密码登陆不了怎么办?
我用的是sql server2008数据库,原先创建的登录名是sa,但是密码就忘了.总是出现这个连接问题
- csharp: 百度语音合成
public string API_id = "3333"; //你的ID public string API_record = null; public string API_r ...