Android Activity各启动模式的差异
Activity共有四种启动模式:standard,singleTop,singleTask,singleInstance
为了方便描述和理解,布局文件、Manifest文件和各个java文件如下:
AndoirdManifest文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.activitylaunchmode"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="21" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:launchMode="standard"
android:screenOrientation="portrait"
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:name=".SecondActivity">
</activity>
<activity
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:name=".ThirdActivity">
</activity>
<activity
android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:name=".FourActivity">
</activity>
</application> </manifest>
4个Activity分别对应一种启动模式:
MainActivity ----> standard (默认模式,写不写都可以)
SecondActivity ----> singleTop
ThirdActivty ----> singleTask
FourActivity ----> singleInstance
布局文件 activity_main.xml
<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.activitylaunchmode.MainActivity" > <TextView
android:id="@+id/mTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:layout_below="@id/mTextView"
android:id="@+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
/>
<Button
android:id="@+id/buttonTwo"
android:text="Button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/buttonOne"
android:layout_below="@id/mTextView"
/>
<Button
android:id="@+id/buttonThree"
android:text="Button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonOne"
/>
<Button
android:id="@+id/buttonFour"
android:text="Button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/buttonTwo"
android:layout_toRightOf="@id/buttonThree"
/>
</RelativeLayout>
MainActivity.java
package com.example.activitylaunchmode; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener{ private static final String TAG = "MainActivity";
TextView tv;
Button ButtonOne;
Button ButtonTwo;
Button ButtonThree;
Button ButtonFour; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.mTextView);
tv.setText("MainActivity");
ButtonOne = (Button) findViewById(R.id.buttonOne);
ButtonOne.setOnClickListener(this);
ButtonTwo = (Button) findViewById(R.id.buttonTwo);
ButtonTwo.setOnClickListener(this);
ButtonThree = (Button) findViewById(R.id.buttonThree);
ButtonThree.setOnClickListener(this);
ButtonFour = (Button) findViewById(R.id.buttonFour);
ButtonFour.setOnClickListener(this);
} @Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
Log.d(TAG, "onNewIntent");
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.buttonOne:
Intent mainIntent = new Intent(this,MainActivity.class);
startActivity(mainIntent);
break;
case R.id.buttonTwo:
Intent secondIntent = new Intent(this,SecondActivity.class);
startActivity(secondIntent);
break;
case R.id.buttonThree:
Intent ThirdIntent = new Intent(this,ThirdActivity.class);
startActivity(ThirdIntent);
break;
case R.id.buttonFour:
Intent FourIntent = new Intent(this,FourActivity.class);
startActivity(FourIntent);
break;
}
}
}
SecondActivity.java
package com.example.activitylaunchmode; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class SecondActivity extends Activity implements OnClickListener { private static final String TAG = "SecondActivity";
TextView tv;
Button ButtonOne;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.mTextView);
tv.setText("SecondActivity");
ButtonOne = (Button) findViewById(R.id.buttonOne);
ButtonOne.setOnClickListener(this);
} @Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
Log.d(TAG, "onNewIntent");
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.buttonOne:
Intent secondIntent = new Intent(this,SecondActivity.class);
startActivity(secondIntent);
break;
}
}
}
ThirdActivity.java
package com.example.activitylaunchmode; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class ThirdActivity extends Activity implements OnClickListener { private static final String TAG = "ThirdActivity";
TextView tv;
Button ButtonOne;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.mTextView);
tv.setText("ThirdActivity");
ButtonOne = (Button) findViewById(R.id.buttonOne);
ButtonOne.setOnClickListener(this);
} @Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
Log.d(TAG, "onNewIntent");
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.buttonOne:
Intent mainIntent = new Intent(this,MainActivity.class);
startActivity(mainIntent);
break; default:
break;
}
} }
FourActivity.java
package com.example.activitylaunchmode; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class FourActivity extends Activity implements OnClickListener { private static final String TAG = "FourActivity";
TextView tv;
Button ButtonOne;
Button ButtonTwo;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.mTextView);
tv.setText("FourActivity");
ButtonOne = (Button) findViewById(R.id.buttonOne);
ButtonOne.setOnClickListener(this);
} @Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
Log.d(TAG, "onNewIntent");
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.buttonOne:
Intent MainIntent = new Intent(this,MainActivity.class);
startActivity(MainIntent);
break; case R.id.buttonFour:
Intent FourIntent = new Intent(this,FourActivity.class);
startActivity(FourIntent);
default:
break;
}
} }
各个启动模式差异探究:
1)standard: 默认模式,每启动一个activity都会在Task中创建一个,back键会依次从栈中退出
MainActivity的启动模式是standard, 点击Button1,会再启动一个MainActivity.
通过adb shell dumpsys activity命令, 我们能看到在Task中存在两个MainActivity.
Task id #
TaskRecord{2cfa2efd # A=com.example.activitylaunchmode U= sz=}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity }
Hist #: ActivityRecord{37783c3a u0 com.example.activitylaunchmode/.MainActivity t48}
Intent { cmp=com.example.activitylaunchmode/.MainActivity }
ProcessRecord{358547f2 :com.example.activitylaunchmode/u0a134}
Hist #: ActivityRecord{363c8000 u0 com.example.activitylaunchmode/.MainActivity t48}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity bnds=[,][,] }
ProcessRecord{358547f2 :com.example.activitylaunchmode/u0a134} Running activities (most recent first):
TaskRecord{2cfa2efd # A=com.example.activitylaunchmode U= sz=}
Run #: ActivityRecord{37783c3a u0 com.example.activitylaunchmode/.MainActivity t48}
Run #: ActivityRecord{363c8000 u0 com.example.activitylaunchmode/.MainActivity t48}
2)singleTop:如果要启动的Activity在栈顶,则不会重新创建
SecondActivity的启动模式是singleTop, 点击MainActivity中的Button2,会创建一个SecondActivity,再点击SecondActivity中的Button1,会重新启动 SecondActivity.
通过adb命令,我们可以看到,Task中只有MainActivity和SecondActivity两个Activity,第二次点击并没有重新创建。从log中,我们可以看到,第二次点击启动SecondActivity,只是调用了前一个SecondActivity的onNewIntent方法。
Task id #
TaskRecord{fb41e01 # A=com.example.activitylaunchmode U= sz=}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity }
Hist #: ActivityRecord{1ea62f6c u0 com.example.activitylaunchmode/.SecondActivity t51}
Intent { cmp=com.example.activitylaunchmode/.SecondActivity }
ProcessRecord{69b44a6 :com.example.activitylaunchmode/u0a134}
Hist #: ActivityRecord{27f7bb0a u0 com.example.activitylaunchmode/.MainActivity t51}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity bnds=[,][,] }
ProcessRecord{69b44a6 :com.example.activitylaunchmode/u0a134} Running activities (most recent first):
TaskRecord{fb41e01 # A=com.example.activitylaunchmode U= sz=}
Run #: ActivityRecord{1ea62f6c u0 com.example.activitylaunchmode/.SecondActivity t51}
Run #: ActivityRecord{27f7bb0a u0 com.example.activitylaunchmode/.MainActivity t51}
3)singleTask: 任务栈中没有这个Activity,则会在任务栈中创建一个实例,如果任务栈中已经存在,则会将任务栈中的此activity之上的activity全部出栈
ThirdActivity的启动模式是singleTask, 点击MainActivity中的Button3,启动ThirdActivity,再点击ThirdActivity中的Button1,启动MainActivity,此时的Activity的堆栈信息如下:
Task id #
TaskRecord{147eed75 # A=com.example.activitylaunchmode U= sz=}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity }
Hist #: ActivityRecord{2bf26a69 u0 com.example.activitylaunchmode/.MainActivity t52}
Intent { cmp=com.example.activitylaunchmode/.MainActivity }
ProcessRecord{3e2f10a :com.example.activitylaunchmode/u0a134}
Hist #: ActivityRecord{147e2631 u0 com.example.activitylaunchmode/.ThirdActivity t52}
Intent { flg=0x10000000 cmp=com.example.activitylaunchmode/.ThirdActivity }
ProcessRecord{3e2f10a :com.example.activitylaunchmode/u0a134}
Hist #: ActivityRecord{4e87389 u0 com.example.activitylaunchmode/.MainActivity t52}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity bnds=[,][,] }
ProcessRecord{3e2f10a :com.example.activitylaunchmode/u0a134} Running activities (most recent first):
TaskRecord{147eed75 # A=com.example.activitylaunchmode U= sz=}
Run #: ActivityRecord{2bf26a69 u0 com.example.activitylaunchmode/.MainActivity t52}
Run #: ActivityRecord{147e2631 u0 com.example.activitylaunchmode/.ThirdActivity t52}
Run #: ActivityRecord{4e87389 u0 com.example.activitylaunchmode/.MainActivity t52}
这个也说明了standard启动模式会重新创建一个Activity.
然后再点击MainActivity中的Button3,启动ThirdActivity,通过adb命令看到的如下:
Task id #
TaskRecord{2553d3b2 # A=com.example.activitylaunchmode U= sz=}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity }
Hist #: ActivityRecord{33f3f7cd u0 com.example.activitylaunchmode/.ThirdActivity t53}
Intent { flg=0x10000000 cmp=com.example.activitylaunchmode/.ThirdActivity }
ProcessRecord{1cdd8f03 :com.example.activitylaunchmode/u0a134}
Hist #: ActivityRecord{e5f9ea5 u0 com.example.activitylaunchmode/.MainActivity t53}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity bnds=[,][,] }
ProcessRecord{1cdd8f03 :com.example.activitylaunchmode/u0a134} Running activities (most recent first):
TaskRecord{2553d3b2 # A=com.example.activitylaunchmode U= sz=}
Run #: ActivityRecord{33f3f7cd u0 com.example.activitylaunchmode/.ThirdActivity t53}
Run #: ActivityRecord{e5f9ea5 u0 com.example.activitylaunchmode/.MainActivity t53}
能看到Task中现在只有两个Activity,ThirdActivity并没有重新创建,靠后的一个MainActivity也被弹出栈,从log也能看出调用了onNewIntent方法,
4)singleInstance: 只有一个实例,运行于独立的task,启动此Activity的时候如果已经创建,则不会重新创建
FourActivity的启动模式是singleInstance,点击MainActivity中的Button4,会启动FourActivity
通过adb shell dumpsys activity命令,我们能看到两个Activity在不同的Task中,
Task id #
TaskRecord{11be8b0d # A=com.example.activitylaunchmode U= sz=}
Intent { flg=0x10000000 cmp=com.example.activitylaunchmode/.FourActivity }
Hist #: ActivityRecord{1cd2b9e5 u0 com.example.activitylaunchmode/.FourActivity t55}
Intent { flg=0x10000000 cmp=com.example.activitylaunchmode/.FourActivity }
ProcessRecord{358d5ac2 :com.example.activitylaunchmode/u0a134}
Task id #
TaskRecord{12e2f0d3 # A=com.example.activitylaunchmode U= sz=}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity }
Hist #: ActivityRecord{374dcd03 u0 com.example.activitylaunchmode/.MainActivity t54}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x30200000 cmp=com.example.activitylaunchmode/.MainActivity bnds=[,][,] }
ProcessRecord{358d5ac2 :com.example.activitylaunchmode/u0a134} Running activities (most recent first):
TaskRecord{11be8b0d # A=com.example.activitylaunchmode U= sz=}
Run #: ActivityRecord{1cd2b9e5 u0 com.example.activitylaunchmode/.FourActivity t55}
TaskRecord{12e2f0d3 # A=com.example.activitylaunchmode U= sz=}
Run #: ActivityRecord{374dcd03 u0 com.example.activitylaunchmode/.MainActivity t54}
如果再点击FourActivity中的Button4,也不会重新创建,从log可以看出,会调用onNewIntent方法,这里就不在贴activity的信息。
adb shell dumpsys activity activities 也可以看到Task中各个activity的 launchMode.
Android Activity各启动模式的差异的更多相关文章
- android Activity的启动模式
Android中Activity启动模式详解 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启 ...
- android Activity的启动模式与flag的见解
最近做一个安卓项目,想要实现的效果就是:当打开一个按钮的时候,启动了一个A功能,当用户返回到桌面再继续进去的时候,不过之前在哪个Activity,都会先跳转到A功能的那个界面,当用户点击返回的时候,再 ...
- 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)
1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...
- Activity的启动模式(android:launchMode)
在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 它们主要有如下不同: ...
- Android开发艺术2之Activity的启动模式
Activity是Android的四大组件之一,他的重要性毋庸置疑,对于这么重要的一个组件,我们首先要知道这些都是由系统进行管理和回调的,要理解Activity的启动模式,我们首先来了解一下Andro ...
- Android开发9——Activity的启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. 一. ...
- 【Android - 组件】之Activity的启动模式
Activity的启动模式目前有四种:standard.singleTop.singleTask 和 singleInstance. 1.standard standard 是标准模式,也是系统的默认 ...
- Android中Activity的启动模式(LaunchMode)和使用场景
一.为什么需要启动模式在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些Ac ...
- Android笔记(五) Activity的启动模式
Android中Activity是由返回栈来管理的,在默认情况下,每当启动一个新的Activity,它都会在返回栈中入栈,并且出于栈的顶端.但是有些时候Activity已经在栈的顶端了,也就不需要再启 ...
随机推荐
- Supporting Multiple Screens 翻译 支持各种屏幕(上)
Supporting Multiple Screens 支持各种各样的屏幕尺寸.屏幕密度 Android runs on a variety of devices that offer differe ...
- 等方案及设备提供商 有需要的可以联系QQ561454825,电话:13779953060,我们提供最专业的无线WIFI认证系统及根据您的需要修改软件
WayOs智能路由.EasyRadius云计费.POE远程供电.WIFI城中村方案.EPON实现FTTB+LAN城中村方案. 等方案及设备提供商 有需要的可以联系QQ561454825,电话:,我们提 ...
- STM32F072B-DISCO 深入研究 中断系统
STM32F072B-DISCO 是我认为性价比最高的一款CPU的demo系统,以前一直在用PIC的CPU但最近几年ST异军突起,几次课题查找芯片无一例外都是ST,像USB,CAN,ZIGBEE等,S ...
- FZYZOJ-1144 恶魔城
P1144 -- 恶魔城 时间限制:1000MS 内存限制:131072KB 状态:Accepted 标签: 图论-最短路 二分 无 Description 上帝需要 ...
- 工作总结之动画与VR
一.Unity5的动画新特性: 1.animator controller默认就包含Any State.Entry.Exit三个状态 2.animator可以给每个动画片段添加脚本,该脚本继承 Sta ...
- AC自动机——多模式串匹配的算法思想
标准KMP算法用于单一模式串的匹配,即在母串中寻求一个模式串的匹配,但是现在又存在这样的一个问题,如果同时给出多个模式串,要求找到这一系列模式串在母串存在的匹配个数,我们应该如何处理呢? 基于KMP算 ...
- Git命令详解(一)-个人使用
本文暂时不会涉及到团队如何使用Git的内容,而是从个人的角度探讨如何用好Git. 约定 绿色的5位字符表示提交的ID,文中用<commit>表示,分别指向父节点.分支用橘色显示,分别指向特 ...
- string.Format字符串格式说明
先举几个简单的应用案例: 1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 ...
- java通过解析文件获取apk版本等信息
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import ...
- poj3693 Maximum repetition substring
题意 给出一个长度为\(n(n\leqslant 100000)\)的串,求一个字典序最小的子串使得它是某个字符串重复\(k\)次得到的,且\(k\)最大 题解 后缀数组论文上的题,跟上一篇uva那个 ...