Android启动activity的4种模式(standard、singleTop、singleTask、singleINstance)
在AndroidManifest.xml中配置activity时,android:launchMode属性会指定启动activity的模式,有四种:
standard
singleTop
singleTask
singleInstance
这四种模式一般配合Intent属性变量FLAG_ACTIVITY_XXX使用,比如FLAG_ACTIVITY_NEW_TASK,本文暂时撇开FLAG_ACTIVITY_XXX,只讨论这四种模式的启动结果,先考虑只在同一个应用下的情况。
standard模式
系统默认情况下就是standard模式,假如A中设置为默认模式,A中有一个按钮,单击按钮时只启动自己,看看启动后的结果。AndroidManifest.xml、A和源码及布局分别为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.administrator.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.example.administrator.myapplication.AActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.feeyan.www.a_activity"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
</application>
</manifest>
|
1
2
3
4
5
6
7
8
9
10
11
12
|
public class AActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_layout);
}
public void startToB(View view) {
startActivity(new Intent("com.feeyan.www.a_activity"));
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.myapplication.AActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="to B"
android:id="@+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:textSize="20sp"
android:onClick="startToB" />
</RelativeLayout>
|
注:本文案例在小米4上测试
假设现在没有运行程序,先通过命令dumpsys activity activities在串口中查看所有activity栈信息:
看红色区域,activity栈中只有一个代号为0的栈,栈中也只有一个id号为#1的task和id号为#0的ActivityRecord,ActivityRecord中保存的包名是com.miui.home,启动类名为.launcher.Launcher,也就是说,目前Activity栈中只有Launcher应用,没有别的应用。
现在启动案例,启动后的栈信息:
案例启动后,系统新建了一个栈stack #1,其中有新启动的Activity实例AActivity,保存在id号为#24的task中
然后,点击按钮再次启动AActivity,启动后的栈信息为:
在同样的stack #1、同样的task #24中多了一个AActicity实例,两个实例对应的ActivityRecord地址不一样,一个是42e23ae0,一个是42da3a08。
默认标准模式,每启动一次,就创建一个新实例,并放到栈顶,并且该实例放在同样的任务task中、同样的activity栈中。不会再新创建栈、task。
singleTop模式
如果把A设为默认Standard标准模式,把B设置singleTop模式,A启动B后看看什么情况,相关源码较简单,不再添加,本文后又源码下载地址。
在stack #1中,新创建了一个task #25,包含B实例和A实例,新启动的实例位于栈顶。如果在B中点击按钮再次启动B,发现栈信息不会改变,而且无论点击多少次按钮,stack #1栈中还是B和A,不会重新创建实例。
假设在A中启动B,B启动C,C设为标准模式,启动后的栈信息:
栈顶是C,其次是B和A,A在栈最底部;如果此时在C中点击按钮再启动B呢?启动后的栈信息:
发现栈顶又创建了一个B实例,不会复用栈中已有的实例,栈中总共有2个B实例!
singleTop模式跟标准Standard模式差不多,只不过多了一种情况,分为两种情况来看:
1. 如果栈中已经有了待启动activity实例并且位于栈顶,那么再次启动该activity时,系统会直接复用该实例,不会再创建新的实例;如果没有,就新创建实例,并放到栈顶;
2. 如果栈中已经有了待启动activity实例,但不在栈顶,那么再次启动该activity时,系统会再次创建新的实例并将该实例放到栈顶,这种情况和standard模式一样。
singleTask模式
如果A和C设置standard模式,B设为singleTask模式,A启动B,B启动C,按照这个顺序启动后,栈中自底向上为:A—–B—–C,如果此时在C中点击按钮再次启动B呢?启动后栈信息为:
此时,Task #30中只有A和B,B位于栈顶,没有C了,这个和singleTop有了明显的差别,在singleTop中C不会消失,而此时C却消失了。
1. 如果栈中已经有了待启动activity实例并且位于栈顶,那么再次启动该activity时,系统会直接复用该实例,不会再创建新的实例;如果没有,就新创建实例,并放到栈顶;
2. 如果栈中已经有了待启动activity实例但不在栈顶,那么再次启动该activity时,系统会复用已有实例,并且把位于该实例之上的所有其他activity实例移出栈,同时将该实例放在栈顶。
singleInstance模式
如果设A和C为standard模式,B为singleInstance模式,A启动B后栈信息为:
发现和上面三种情况都不一样的地方,在栈中新创建了一个task,并把B放入其中,上面三种情况都是在同样的task中。如果再B中启动C,启动后的栈:
A和C都是标准模式,都在同一个task中,而B在另外一个task中,因为启动了C,C在栈顶。如果再C中点击按钮再次启动B,结果会是什么?
B所在的task跑到了栈顶,A和C所在的task在栈底。而且B始终只有一个实例。
1. 如果栈中没有待启动activity实例,启动该activity时,系统会新创建一个task,再创建一个待启动activity实例,把该实例放到新task中,并且该task会在栈顶;
2. 如果栈中已经有了待启动activity实例,不管在栈的什么位置,系统都会复用已存在实例,并且把该实例放在栈顶,而且该task中只有一个该实例,不会再有第二个实例,也不会有其他activity实例;
3. 如果一个应用中有多个activity都设置成singleInstance模式,那么每个启动后的activity实例都保存在一个task中,不会在同一个task中,task和实例是一对一关系。
同一应用中测试小结
a. standard、singleTop存在多种实例的可能(“可能”二字表明,singleTop情况下,如果栈顶已有实例,再次启动时只会复用,如果不在栈顶,就会新创建实例);而singleTask和singleInstance只有一个实例,再次启动时不会创建新实例;
b. singleTask和singleInstance模式,再次调用时都会先调用onNewIntent方法,再调用onResume方法;对于singleTop,如果栈顶已有实例,也是先调用onNewIntent方法,再调用onResume方法,如果不在栈顶或者还没有实例,就会先调用onCreate方法;
c. singleInstance模式不同于其他三种,首次启动时会新开启一个task,该task只包含一个实例;再次启动时只会复用该task,不再新创建。
同一应用中只有1个app,源码地址:https://yunpan.cn/crybfHCWhcbwW 访问密码:e7cb
不同应用之间测试小结
上面分析了在同一应用中的情况,再看看不同应用之间的情形。通过测试得知:standard、singleTop没有什么改变,还是在在同样的栈、task中;singleInstance模式下也没有改变,还是会创建新的task并保存唯一实例;但singleTask却不一样,首次启动时,系统会在当前栈中创建一个新的task,再次启动时,复用已有task;而在同一应用中,再次启动时,不会再创建新task的,直接复用已有task。
不同应用之间测试有2个app,源码地址:https://yunpan.cn/crKLt2CuZ7drc 访问密码 e4b8
最终总结
不管是同一应用中还是不同应用之间,standard、singleTop、singleInstance各自没有区别,只有singleTask不一样,同一应用中不创建新的task,不同应用中有可能会创建新的task。(注:这里用到了“可能”二字,没有用“一定”,是因为这与taskAffinity属性有关,如果设置了此属性,就会在该属性对应的task中启动实例,否则,会创建新的task)。
转自:feeyan
Android启动activity的4种模式(standard、singleTop、singleTask、singleINstance)的更多相关文章
- Android -- Activity的生命周期,Activity四种启动模式 Standard, SingleTop,SingleTask,SingleInstance
1. 示例图 . 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: Activity的完整生命周期自第一次调用onCreate()开始,直至调 ...
- Android启动Activity的两种方式与四种启动模式
1.在一个Activity中调用startActivity()方法 2.在一个Activity中调用startActivityRequest()方法. 重写onActivityResult方法,用来接 ...
- Android学习笔记_50_(转 四种加载方式详解(standard singleTop singleTask singleInstance)
Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...
- Android 四种加载方式详解(standard singleTop singleTask singleInstance) .
Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...
- Activity的启动模式全解standard,singleTop,singleTask,singleInstance
在android中控制Activity的启动模式的属性主要控制两大功能: 1,控制activity 进入哪一个任务task 中, 有两种可能,进入启动task中,进入指定taskAffinity的 ...
- "standard,singleTop,singleTask,singleInstance"-Android启动模式
安卓有4种启动模式,下面我们就进行详细的讲解 用栈的思维去理解,就能理解这些启动模式的本质了 先设置两个页面: A(为测试对象),B两个页面,两个页面都有跳至对方的按钮 一.标准模式(standard ...
- Android [启动方式:standard singleTop singleTask singleInstance]
栈顶Activity是当前正在显示的. 以A.B举例 1.standard 不同的Activity都存放在同一个栈中,每次创建实例都会堆放到栈顶,逐次返回直至退出. 创建实例B 创建实例A 点击返回时 ...
- Android 启动Activity的方式
Activity的启动分为两种方式,显示方式和隐式方式,显示方式就是在通过intent启动Activity时指定了Activity的包名和类名. 而隐式方式则在初始化Intent时仅仅指定action ...
- Android系统中的6种模式
Android系统中的6种模式 1:一般启动模式(normal mode): 功能是正常启动手机,方法为关机状态下按电源键启动. 2:安全模式(safe mode): 此模式和正常启动一样 ...
随机推荐
- 01-05-01-1【Nhibernate (版本3.3.1.4000) 出入江湖】延迟加载及其class和集合(set、bag等)的Lazy属性配置组合对Get和Load方法的影响
这篇文章 http://ayende.com/blog/3988/nhibernate-the-difference-between-get-load-and-querying-by-id One o ...
- 建立docker私有hub
docker是一个非常好用的虚拟化工具. 下面给出建立私有docker hub的方法.docker将私有hub的环境打包在registry image中 执行指令: docker run -p 500 ...
- POJ 2349 Arctic Network(最小生成树,第k大边权,基础)
题目 /*********题意解说——来自discuss——by sixshine**************/ 有卫星电台的城市之间可以任意联络.没有卫星电台的城市只能和距离小于等于D的城市联络.题 ...
- Android ActionBar 关于tab的应用 以及 TabListener的方法详解
actionBar的tab标签应用以及TabListener的方法详解 package com.example.actionBarTest.actionBarTab; import android.a ...
- http://www.aboutyun.com/thread-8792-1-1.html
http://www.aboutyun.com/thread-8792-1-1.html
- hdu 1180 诡异的楼梯
诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Subm ...
- Bessie的体重问题
P1028 Bessie的体重问题 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 USACO OCT09 8TH 描述 Bessie像她的诸多姊妹一样,因 ...
- Project Euler 88:Product-sum numbers 积和数
Product-sum numbers A natural number, N, that can be written as the sum and product of a given set o ...
- Python批量读取人脸图片与数据互相转换
读取部分结果 程序 # -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt from PIL import ...
- ios开发--27个提升效率的iOS开源库推荐
超长慎入列表: DZNEmptyDataSet(UI,空表格视图解算器) PDTSimpleCalendar(UI,drop-in日历组件) MagicalRecord(实施活跃记录模式的Core D ...