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已经在栈的顶端了,也就不需要再启 ...
随机推荐
- PYTHON调用JENKINS的API来进行CI
我查到的相关API有两套,我主要用的是python-jenkins. https://pypi.python.org/pypi/python-jenkins/ 按语法调用即可... import je ...
- Windows消息对Edit控件的处理
例如对windows发消息让文本选中. SendMessage(Text1.hwnd,EM_GETSEL,0,-1 ); EC_LEFTMARGIN(&H1) EC_USEFONTINF // ...
- Erlang安装简介
什么是 Erlang? Erlang 由 Ericsson (爱立信公司)开发,用于帮助开发管理许多电信项目的软件.Erlang 的第一个版本发布于 1986 年,1998 年发布了它的第一个开放源码 ...
- eclipse 导入Android项目时报告 Invalid Project Description
现象描述: 1.新建Android项目XX2.删除Android项目XX3.使用Existing Android Code Into Workspace(EACIW)导入Android项目XX,报错: ...
- bzoj2653
CLJ神牛的可持久化论文的题目,果然厉害其实第一步能想到后面就还是很简单的首先是二分答案,转化为判定性问题然后对于区间内的数,比他大的标为1,小的标为-1显然,如果存在一个左右端点符合的区间使得这个区 ...
- 数据库连接&数据库进程&数据库操作
root@webwall:/home/xiachengjiao# vi/webwall/mysql/my.cnf(看配置文件中的参数) root@webwall:/webwall/mysql/bin# ...
- 【转】VS 代码行数统计
[转自]http://www.cnblogs.com/JuneZhang/archive/2013/01/10/2854572.html VS用正则表达式统计代码行数 利用VS2010的查找功能和正则 ...
- SSH隧道技术----端口转发,socket代理
原文的原始出处不详,本文也是在复制引用了某篇转载,并做了必要的整理与编辑. 本文的受众 如果你遇到了以下问题,那么你应该阅读这篇文章 我听说过这种技术,我对它很感兴趣 我想在家里访问我在公司的机器(写 ...
- poj 1329 Circle Through Three Points(求圆心+输出)
题目链接:http://poj.org/problem?id=1329 输出很蛋疼,要考虑系数为0,输出也不同 #include<cstdio> #include<cstring&g ...
- 大牛博客!Spark / Hadoop / Kafka / HBase / Storm
在这里,非常感谢下面的著名大牛们,一路的帮助和学习,给予了我很大的动力! 有了Hadoop,再次有了Spark,一次又一次,一晚又一晚的努力相伴! HBase简介(很好的梳理资料) 1. 博客主页:h ...