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各启动模式的差异的更多相关文章

  1. android Activity的启动模式

    Android中Activity启动模式详解   在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启 ...

  2. android Activity的启动模式与flag的见解

    最近做一个安卓项目,想要实现的效果就是:当打开一个按钮的时候,启动了一个A功能,当用户返回到桌面再继续进去的时候,不过之前在哪个Activity,都会先跳转到A功能的那个界面,当用户点击返回的时候,再 ...

  3. 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)

    1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...

  4. Activity的启动模式(android:launchMode)

    在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 它们主要有如下不同: ...

  5. Android开发艺术2之Activity的启动模式

    Activity是Android的四大组件之一,他的重要性毋庸置疑,对于这么重要的一个组件,我们首先要知道这些都是由系统进行管理和回调的,要理解Activity的启动模式,我们首先来了解一下Andro ...

  6. Android开发9——Activity的启动模式

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. 一. ...

  7. 【Android - 组件】之Activity的启动模式

    Activity的启动模式目前有四种:standard.singleTop.singleTask 和 singleInstance. 1.standard standard 是标准模式,也是系统的默认 ...

  8. Android中Activity的启动模式(LaunchMode)和使用场景

    一.为什么需要启动模式在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些Ac ...

  9. Android笔记(五) Activity的启动模式

    Android中Activity是由返回栈来管理的,在默认情况下,每当启动一个新的Activity,它都会在返回栈中入栈,并且出于栈的顶端.但是有些时候Activity已经在栈的顶端了,也就不需要再启 ...

随机推荐

  1. INDEX FAST FULL SCAN和INDEX FULL SCAN

    INDEX FULL SCAN 索引全扫描.单块读 .它扫描的结果是有序的,因为索引是有序的.它通常发生在 下面几种情况(注意:即使SQL满足以下情况 不一定会走索引全扫描) 1. SQL语句有ord ...

  2. 创办支持多种屏幕尺寸的Android应用

    创建支持多种屏幕尺寸的Android应用 Android涉及各种各样的支持不同屏幕尺寸和密度的设备.对于应用程序,Android系统通过设备和句柄提供了统一的开发环境,大部分工作是校正每一个应用程序的 ...

  3. C - Point on Spira

      Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Pr ...

  4. Linux驱动的两种加载方式过程分析

    一.概念简述 在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用.静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新 ...

  5. php 中 global 与 $GLOBAL 由引用产生的区别

    很多人都认为global和$GLOBALS[]只是写法上面的差别,其实不然. 根据官方的解释是 $GLOBALS['var'] 是外部的全局变量$var本身. global $var 是外部$var的 ...

  6. 用cmd改计算机名.bat 无需重启电脑生效

    echo offset /p cname=请输入计算机名: echo REGEDIT4 >reg.reg echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentContr ...

  7. OpenStack G版以后的Availability Zone与Aggregate Hosts

    关于Availability Zone与Aggregate Hosts的概念解析,可以参考这篇文章:http://blog.chinaunix.net/uid-20940095-id-3875022. ...

  8. nyoj 32 组合数【简单dfs】

    组合数 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 找出从自然数1.2.... .n(0<n<10)中任取r(0<r<=n)个数的所有组合 ...

  9. kafka集群扩容以及数据迁移

    一 kafka集群扩容比较简单,机器配置一样的前提下只需要把配置文件里的brokerid改一个新的启动起来就可以.比较需要注意的是如果公司内网dns更改的不是很及时的话,需要给原有的旧机器加上新服务器 ...

  10. 【转】eclipse使用git提交到osc

    转自:http://my.oschina.net/gaowm/blog/271623 目录[-] 一.Git下载 二.Git安装 三.设置用户名和密码 四.准备代码库 五.创建本地仓库 六.eclip ...