黑发不知勤学早,白首方悔读书迟。——《劝学》
Activity的四种启动模式,如有疑问欢迎留言,如有谬误欢迎大家批评指正,谢谢
Activity的启动模式共有四种
1.standard
2.singleTop
3.singleTask
4.singleInstance
如图所示:
LaunchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。
下面我们就依次来说说这几种启动模式
1.standard
standard模式是Activity默认的启动模式,当我们在没有配置activity的launchMode时它就会按照standard方式去启动,
下面通过一个实例来解释下这种启动模式
FirstActivity代码如下:
- package com.example.activitylauchmodepractice;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class FirstActivity extends Activity {
- private Button btn_jumpToSecondActivity;
- private TextView tv_showViewClass;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_first);
- tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);
- tv_showViewClass.setText(FirstActivity.this.toString());
- btn_jumpToSecondActivity=(Button) findViewById(R.id.btn_jumpToSecondActivity);
- btn_jumpToSecondActivity.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent=new Intent(FirstActivity.this,FirstActivity.class);
- startActivity(intent);
- }
- });
- }
- }
启动后的界面
此时它所对应的任务栈如下
在此基础上我们点击按钮再次启动Activity此时的界面如下
此时的任务栈变化过程如下
我们再次点击按钮跳转到FirstActivity界面如下
此时的任务栈的变化过程如下
好了到这我们就可以分析一下了,在上述过程中我们点击了三次按钮它实例化了三个FirstActivity
这就是standard模式的特点:不管任务栈中有没有实例存在它都会实例化一个Activity
当我们点击返回按钮时它会依次把最上面的Activity出栈,上面的过程中一共实例化了三个Activity因此我们需要点击三次返回按钮应用才能退出。
2.singleTop
还用上面那个例子,此时我们给FirstActivity的属性指定为:android:launchMode="singleTop"
启动后的界面
此时的任务栈如下
我们接着点击按钮发现无论点击几次界面都没变说明它只实例化一次,此时的任务站始终是一个Activity此时点击一次返回键便可退出应用。
这是只有一个Activity的情况,下面我们说说多个Activity的情况
再来一个SecondActivity代码如下:
- package com.example.activitylauchmodepractice;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class SecondActivity extends Activity {
- private Button btn_jumpToFirstActivity_;
- private TextView tv_showViewClass;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_second);
- tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);
- tv_showViewClass.setText(SecondActivity.this.toString());
- btn_jumpToFirstActivity_=(Button) findViewById(R.id.btn_jumpToFirstActivity);
- btn_jumpToFirstActivity_.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent=new Intent(SecondActivity.this, FirstActivity.class);
- startActivity(intent);
- }
- });
- }
- }
把FirstActivity的代码稍作修改
- btn_jumpToSecondActivity.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
- startActivity(intent);
- }
- });
在上面的Activity中FirstActivity的启动模式是singleTop,SecondActivity的启动模式是默认的standard,做好准备之后我们来做操作
启动后的界面如下:
此时的任务栈如下
在此基础上我们点击一次按钮界面如下
此时的任务栈的变化如下
在SecondActivity中再次点击按钮的界面如下
此时的任务栈的变化如下
从上面的过程中我们看到再次从SecondActivity跳转到FirstActivity时两次的FirstActivity的序列号不同说明又重新生成了一个FirstActivity
singleTop模式的特点:当从SecondActivity跳转到FirstActivity时,系统发现存在有FirstActivity实例,但不是位于栈顶,于是重新生成一个实例。这就是singleTop启动模式的特点,即如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例,如果栈顶没有对应的Activity则实例化一个。
该模式和standard模式基本一致,但有一点不同,当将要被启动的Activity已经位于Task栈顶时,系统不会重新创建目标Activity的实例,而是直接复用Task栈顶的Activity
3.singleTask(内单例模式)
我们还是建立在上面的基础上,把FirstActivity的启动模式改为android:launchMode="singleTask"
启动后我们点击三次跳转按钮界面如下图所示
在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号是改变的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。
在此过程中任务栈的变化过程如下
在上面的跳转过程中当从SecondActivity跳转到FirstActivity时发现SecondActivity消失了,这就是singleTask的特点在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。
singleTask模式的特点:如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
Activity在同一个Task内只有一个实例. 当系统采用singleTask模式加载Activity时,又分为以下三种情况:
(1)如果将要启动的Activity不存在,那么系统将会创建该实例,并将其加入Task栈顶
(2)如果将要启动的Activity已存在,且存在栈顶,那么此时与singleTop模式的行为相同
(3)如果将要启动的Activity存在但是没有位于栈顶,那么 此时系统会把位于该Activity上面的所有其他Activity全部移出Task,从而使得该目标Activity位于栈顶
4.singleInstance(全局单例模式)
这种模式是四种模式中最难理解的一种模式,因为这种模式会重新创建一个新的任务栈,将Activity放置于这个栈中,并保证其它的Activity不再进入,由于这种模式比较复杂,我们首先来说说它的原理,然后再结合实例进一步的理解,假如现在用户打开了两个应用分别为应用1和应用2,应用1和应用2的任务栈假如如下图左边,此时在应用1中想打开Activity3,这时应用1和应用2就会共享Activity3的引用,
注意:之所以能公用Activity的引用是以应用2中的Activity设置了LaunchMode="singleInstance"为前提的。
由于这种模式比较复杂,我们举两个不同例子,来说明不同的问题
举例一、
还是上面的两个Activity。FirstActivity和SecondActivity在两个Activityt跳转的过程中我们打印两个Activity所在的任务栈的ID
对以上两个Activity做如下修改,并且把SecondActivity的启动模式改为singleInstance
- tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);
- tv_showViewClass.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());
启动后和点击跳转按钮后的界面如下
我们发现两个Activity的TaskId是不同的,说明这两个Activity是位于不同的任务栈中的,从而证实了为SecondActivity重新建立了一个任务栈,可能有的朋友会问,在这个时候如果点击返回按钮它们是怎么出栈的呢?假如现在我们点击返回按钮它的任务栈的变化如下图
假如我们在SecondActivity中点击按钮跳转到FirstActivity然后会以怎样的方式退出应用呢?此时 它的任务栈的变化如下
图中下半部分显示的在SecondActivity中再次跳转到FirstActivity,这个时候系统会在原始栈结构中生成一个FirstActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到FirstActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。
由于singleInstance比较复杂些,我们再来举一个两个应用的例子为了和上面的例子混淆,我们重新写两个应用
第一个App中有两个Activity分别为Activity1和ShareActivity
第二个App中有一个Activity2我们在这个App中启动第一个App的ShareActivity
第一个App的Activity源码如下
- package com.example.activitylauchmodepractice;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class Activity1 extends Activity {
- private Button btn_jumpToSecondActivity;
- private TextView tv_showViewClass;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_first);
- tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);
- tv_showViewClass.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());
- btn_jumpToSecondActivity=(Button) findViewById(R.id.btn_jumpToSharedActivity);
- btn_jumpToSecondActivity.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent=new Intent(Activity1.this,ShareActivity.class);
- startActivity(intent);
- }
- });
- }
- }
ShareActivity源码
- package com.example.activitylauchmodepractice;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class ShareActivity extends Activity {
- private Button btn_jump;
- private TextView tv_showViewClass;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_second);
- tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);
- tv_showViewClass.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());
- }
- }
我们要特别注意ShareActivity在清单文件中的配置如下
- <activity
- android:name="com.example.activitylauchmodepractice.ShareActivity"
- android:launchMode="singleInstance">
- <intent-filter>
- <action android:name="SecondActivity_action"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </activity>
我们需要配置ShareActivity的action在另一个应用中启动时会用到
第二个App中的Activity2的源码如下
- package com.example.singleinstancepractice;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- private Button btn_jump;
- private TextView tv_showTaskId;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- tv_showTaskId=(TextView) findViewById(R.id.tv_showTaskId);
- tv_showTaskId.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());
- btn_jump=(Button) findViewById(R.id.btn_jump);
- btn_jump.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent =new Intent();
- intent.setAction("SecondActivity_action");
- startActivity(intent);
- }
- });
- }
- }
当我们在第一个App中打开ShareActivity后再按后退键回到原来界面时,ShareActivity做为一个独立的个体存在,如果这时我们在第二个App中打开ShareActivity无需创建新的ShareActivity实例即可看到结果,因为系统会自动查找,存在则直接利用。原理图如下:
注意:上图是建立在第一个App运行到手机上时点击第二个App上的跳转按钮跳转到ShareActivity的情况的基础上的变化过程。
相关推荐
本项目提供了对Android Activity四种启动模式的实例演示,让我们逐一深入理解这四种模式。 1. standard(标准模式) 这是Activity的默认启动模式。在standard模式下,每次启动一个Activity都会创建一个新的实例,...
了解和掌握不同的Activity启动模式对于优化应用程序的行为至关重要。本文将详细讲解四种主要的Activity启动模式:standard、singleTop、singleTask以及singleInstance,并通过实际案例分析它们的应用场景。 1. ...
在Android应用开发中,Activity是用户界面的基本组件,它负责与用户进行交互。理解Activity的启动模式至关...在实际项目中,灵活运用Activity启动模式,可以有效地管理应用的生命周期,避免资源浪费,提升应用性能。
本示例项目“Android中Activity启动模式demo”旨在帮助开发者深入理解Activity的不同启动模式,以便更好地控制应用的行为和流程。Activity有四种基本的启动模式:标准模式(Standard)、单实例模式(SingleInstance...
在Android应用开发中,Activity是用户界面的基本单元,它的启动模式是决定Activity如何启动和运行的关键因素。Android提供了四种不同的启动模式:标准模式(Standard)、单实例模式(SingleTop)、单任务模式...
综上所述,掌握Activity启动模式是Android开发中的重要技能,可以根据实际需求选择合适的模式,提升应用性能和用户体验。"Activity启动模式demo"这个实例提供了一个很好的学习平台,通过实践操作加深理解。
标准模式是最常见的Activity启动模式,每个启动请求都会创建一个新的Activity实例。如果新的实例被叠加到栈顶,那么它会覆盖之前显示的Activity。这种模式适用于大部分Activity,因为它允许灵活的导航和回退操作,...
一、Activity启动模式概述 1. **标准模式(Standard)**:这是Activity的默认启动模式,每次启动都会创建一个新的实例,无论是否已在栈中存在。因此,同一个Activity可能会有多个实例。 2. **单实例模式...
在Android应用开发中,Activity是用户界面的基本...综上所述,掌握和运用Android的Activity启动模式是提升应用功能和用户体验的关键技能之一。通过深入学习和实践,开发者可以创造出更多超炫的特效和流畅的交互设计。
本文将深入探讨Android的四种Activity启动模式:标准模式(Standard)、单实例模式(SingleInstance)、单任务模式(SingleTask)和单栈顶模式(SingleTop),并结合实际代码示例进行详细解析。 1. 标准模式...
在 Android 应用开发中,Activity 是构成应用的基本单元之一,它负责显示用户界面并处理用户交互。为了更好地控制 Activity 的启动方式以及它们在任务栈中的行为,Android 提供了四种不同的启动模式,即 `standard`...
在Android应用开发中,Activity是用户界面的主要载体,它的启动模式是决定Activity如何启动和运行的关键因素。...通过这种方式,开发者能够更好地掌握Activity启动模式的使用,提高应用的健壮性和用户体验。
标准模式是最常见的Activity启动模式,每个启动请求都会创建一个新的Activity实例。如果新的实例被压入到栈顶,那么就会出现多个相同实例的情况。这种模式适用于大多数Activity,因为它们通常不需要特殊的行为管理...
此篇博客意在让对启动模式不了解的开发者对其有一个较为形象的认识,至于深入探究,笔者还是推荐去看任玉刚前辈所写的《android开发艺术探索》了。 网上对Activity的启动模式讲解的博客有很多,但是大部分都需要掌握...
一、Activity启动模式概述 Activity的启动模式主要分为四种: 1. standard(标准模式):每次启动都会创建一个新的Activity实例,不论栈中是否存在该Activity。 2. singleTop(栈顶复用模式):如果新启动的Activity...
在Android应用开发中,Activity是用户界面的基本组件,它的启动模式是决定Activity如何启动和管理的关键因素。了解和掌握Activity的四种启动模式对于优化用户体验和应用性能至关重要。 1. **standard模式** 这是最...
Activity启动模式是Android系统管理Activity实例的重要机制,它决定了当用户点击一个应用或在应用内部进行跳转时,如何创建和管理Activity的生命周期。本示例项目"Activity启动模式实例"深入探讨了四种主要的...
如果需要在新的Activity启动后关闭当前Activity,可以使用startActivityForResult(),并在TargetActivity中调用setResult()返回结果。 四、传递参数 1. 通过Intent的putExtra()方法传递基本类型数据: ```java ...
在Android应用开发中,Activity是用户界面的基本组件,它的启动模式是开发者必须了解的重要概念。本文将深入探讨Android中Activity的四种启动模式:标准模式(Standard)、单实例模式(SingleInstance)、单任务模式...