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. rest开发

    http://www.mkyong.com/webservices/jax-rs/download-json-from-jax-rs-with-jaxb-resteasy/ http://blog.j ...

  2. JavaService wrapper

    http://my.oschina.net/yjwxh/blog/260835 http://blog.chinaunix.net/uid-664509-id-3398193.html http:// ...

  3. 使用mysql-proxy代理实现msyql数据库读写分离

    要实现读写分离,可以先看看如何实现mysql数据库主从:http://www.cnblogs.com/sustudy/p/4174189.html mysql-proxy下载地址(要看好对应版本):h ...

  4. 从零开始制作jffs2文件系统

    JFFS2 是一个开放源码的项目(www.infradead.org). 它是在闪存上使用非常广泛的读/写文件系统,在嵌入式系统中被普遍的应用. 1.       安装mkfs工具 MTD主页:htt ...

  5. iframe详细用法

    <iframe>是框架的一种形式,也比较常用到. 例子1.<iframe width=420 height=330 frameborder=0 scrolling=auto src= ...

  6. 译文: async/await SynchronizationContext 上下文问题

    async / await 使异步代码更容易写,因为它隐藏了很多细节. 许多这些细节都捕获在 SynchronizationContext 中,这些可能会改变异步代码的行为完全由于你执行你的代码的环境 ...

  7. position: absolute 的元素自动对齐父元素 border 外边缘

    Position with border outer edge CSS box-flex align-items justify-content

  8. (转)ASP.NET MVC路由配置

    一.命名参数规范+匿名对象 1 routes.MapRoute(name: "Default", 2 url: "{controller}/{action}/{id}&q ...

  9. android.mk android源码编译

    http://www.cnblogs.com/chenbin7/archive/2013/01/05/2846863.html Android.mk简单分析 2013-01-05 22:51 by . ...

  10. MongoDB基础知识 02

    MongoDB基础知识 02 6 数据类型 6.1 null : 表示空值或者不存在的字段 {"x":null} 6.2 布尔型 : 布尔类型只有两个值true和false {&q ...