`

Android开发之Activity的启动模式

    博客分类:
  • Java
阅读更多

黑发不知勤学早,白首方悔读书迟。——《劝学》

 

    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代码如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.activitylauchmodepractice;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.TextView;  
  10.   
  11. public class FirstActivity extends Activity {  
  12.       
  13.     private Button btn_jumpToSecondActivity;  
  14.     private TextView tv_showViewClass;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_first);  
  20.           
  21.         tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);  
  22.         tv_showViewClass.setText(FirstActivity.this.toString());  
  23.           
  24.         btn_jumpToSecondActivity=(Button) findViewById(R.id.btn_jumpToSecondActivity);  
  25.         btn_jumpToSecondActivity.setOnClickListener(new OnClickListener() {  
  26.               
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 Intent intent=new Intent(FirstActivity.this,FirstActivity.class);  
  30.                 startActivity(intent);  
  31.             }  
  32.         });  
  33.     }  
  34.       
  35. }  

启动后的界面

 

 

此时它所对应的任务栈如下

在此基础上我们点击按钮再次启动Activity此时的界面如下

 

 

此时的任务栈变化过程如下

 

我们再次点击按钮跳转到FirstActivity界面如下

 

此时的任务栈的变化过程如下

 

好了到这我们就可以分析一下了,在上述过程中我们点击了三次按钮它实例化了三个FirstActivity

这就是standard模式的特点:不管任务栈中有没有实例存在它都会实例化一个Activity

当我们点击返回按钮时它会依次把最上面的Activity出栈,上面的过程中一共实例化了三个Activity因此我们需要点击三次返回按钮应用才能退出。

2.singleTop

 

还用上面那个例子,此时我们给FirstActivity的属性指定为:android:launchMode="singleTop"

启动后的界面

 

此时的任务栈如下

我们接着点击按钮发现无论点击几次界面都没变说明它只实例化一次,此时的任务站始终是一个Activity此时点击一次返回键便可退出应用。

这是只有一个Activity的情况,下面我们说说多个Activity的情况

再来一个SecondActivity代码如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.activitylauchmodepractice;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.TextView;  
  10.   
  11. public class SecondActivity extends Activity {  
  12.       
  13.     private Button btn_jumpToFirstActivity_;  
  14.     private TextView tv_showViewClass;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_second);  
  20.           
  21.         tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);  
  22.         tv_showViewClass.setText(SecondActivity.this.toString());  
  23.           
  24.         btn_jumpToFirstActivity_=(Button) findViewById(R.id.btn_jumpToFirstActivity);  
  25.         btn_jumpToFirstActivity_.setOnClickListener(new OnClickListener() {  
  26.               
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 Intent intent=new Intent(SecondActivity.this, FirstActivity.class);  
  30.                 startActivity(intent);  
  31.             }  
  32.         });  
  33.     }  
  34. }  

把FirstActivity的代码稍作修改

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. btn_jumpToSecondActivity.setOnClickListener(new OnClickListener() {  
  2.               
  3.             @Override  
  4.             public void onClick(View v) {  
  5.                 Intent intent=new Intent(FirstActivity.this,SecondActivity.class);  
  6.                 startActivity(intent);  
  7.             }  
  8.         });  

在上面的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

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 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源码如下

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.activitylauchmodepractice;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.TextView;  
  10.   
  11. public class Activity1 extends Activity {  
  12.       
  13.     private Button btn_jumpToSecondActivity;  
  14.     private TextView tv_showViewClass;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_first);  
  20.           
  21.         tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);  
  22.         tv_showViewClass.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());  
  23.           
  24.         btn_jumpToSecondActivity=(Button) findViewById(R.id.btn_jumpToSharedActivity);  
  25.         btn_jumpToSecondActivity.setOnClickListener(new OnClickListener() {  
  26.               
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 Intent intent=new Intent(Activity1.this,ShareActivity.class);  
  30.                 startActivity(intent);  
  31.             }  
  32.         });  
  33.     }  
  34.       
  35. }  

ShareActivity源码

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.activitylauchmodepractice;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.TextView;  
  10.   
  11. public class ShareActivity extends Activity {  
  12.       
  13.     private Button btn_jump;  
  14.     private TextView tv_showViewClass;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_second);  
  20.           
  21.         tv_showViewClass=(TextView) findViewById(R.id.tv_showViewClass);  
  22.         tv_showViewClass.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());  
  23.           
  24.     }  
  25. }  


我们要特别注意ShareActivity在清单文件中的配置如下

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <activity   
  2.      android:name="com.example.activitylauchmodepractice.ShareActivity"  
  3.      android:launchMode="singleInstance">  
  4.         <intent-filter>  
  5.              <action android:name="SecondActivity_action"/>  
  6.              <category android:name="android.intent.category.DEFAULT"/>  
  7.           </intent-filter>  
  8.               
  9. </activity>  


我们需要配置ShareActivity的action在另一个应用中启动时会用到
第二个App中的Activity2的源码如下

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.singleinstancepractice;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.TextView;  
  10.   
  11. public class MainActivity extends Activity {  
  12.       
  13.     private Button btn_jump;  
  14.     private TextView tv_showTaskId;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_main);  
  20.         tv_showTaskId=(TextView) findViewById(R.id.tv_showTaskId);  
  21.         tv_showTaskId.setText("当前Activity:"+"\n"+this.toString()+"\n"+"当前TaskId:"+this.getTaskId());  
  22.         btn_jump=(Button) findViewById(R.id.btn_jump);  
  23.         btn_jump.setOnClickListener(new OnClickListener() {  
  24.               
  25.             @Override  
  26.             public void onClick(View v) {  
  27.                 Intent intent =new Intent();  
  28.                 intent.setAction("SecondActivity_action");  
  29.                 startActivity(intent);  
  30.             }  
  31.         });  
  32.     }  
  33. }  

当我们在第一个App中打开ShareActivity后再按后退键回到原来界面时,ShareActivity做为一个独立的个体存在,如果这时我们在第二个App中打开ShareActivity无需创建新的ShareActivity实例即可看到结果,因为系统会自动查找,存在则直接利用。原理图如下:

注意:上图是建立在第一个App运行到手机上时点击第二个App上的跳转按钮跳转到ShareActivity的情况的基础上的变化过程。

分享到:
评论

相关推荐

    Android中Activity启动模式demo

    android开发中activity不同启动模式的学习,通过不同的activity启动,会在activity中显示task ID 和Android 实例,方便学习activity的启动模式。

    android Activity 四种启动模式例子

    Android的Activity一共有4中启动模式分别是:standard、singleTop、singleTask、singleInstance。资源是该例子的项目,直接导入项目即可。

    android activity4种启动模式测试

    android activity4种启动模式测试 一个演示启动模式的demo,结合博文,可以很方便的熟悉各种启动模式之间的差异。

    android Activity的启动模式 作用简析+demo详解

    此篇博客意在让对启动模式不了解的开发者对其有一个较为形象的认识,至于深入探究,笔者还是推荐去看任玉刚前辈所写的《android开发艺术探索》了。 网上对Activity的启动模式讲解的博客有很多,但是大部分都需要掌握...

    Android开发-Activity的生命周期及Intent

    4. 掌握Activity的启动模式,和启动模式所对应的Activity和task的关系 内容: 1、设计如下界面,包括四个按钮,两个文本框。单击对应按钮可以启动对应activity。假 定Activity A为启动Activity。 2、修改 Activity ...

    Android开发之Activity详解

    【Activity】  一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号、拍照、发送email、看地图。每一个activity被给予一个窗口,在上面...每一次一个activity启动,前一个ac

    Android编程中Activity的四种启动模式

    本文实例讲述了Android编程中Activity的四种启动模式。分享给大家供大家参考,具体如下: Activity启动方式有四种,分别是: standard singleTop singleTask singleInstance 可以根据实际的需求为Activity设置对应的...

    安卓开发观察者模式应用-一个service通知多个activity更新ui的实现

    安卓开发观察者模式应用-一个service通知多个activity更新ui的实现, service与activity的交互: 1.接口回调 2.自定义广播 3.观察者模式

    Android实验二:Activity的生命周期及Intent

    1、设计界面,包括四个按钮,两个文本框。单击对应按钮可以启动对应activity。假定Activity A为启动...2、修改 Activity 的启动模式 LaunchMode,并通过 Log 信息来体会不同启动模式所对应的Activity 和 task 的关系

    android开发资料大全

    Android开发开发技巧之 EditText 属性、 ProgressBar 各种样式大全 android用户界面之EditText教程实例汇 android用户界面之ListView教程实例汇 android用户界面之Toast教程实例汇 android用户界面之AlarmManager...

    Android开发案例驱动教程 配套代码

    《Android开发案例驱动教程》 配套代码。 注: 由于第12,13,14章代码太大,无法上传到一个包中。 这三节代码会放到其他压缩包中。 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式...

    android开发技巧100条.docx

    Java/Kotlin基础:牢固掌握Java或Kotlin语言基础知识,因为它们是Android开发的主要编程语言。...Intent与启动模式:学会使用Intent进行组件间的通信和页面跳转,理解并掌握四种不同的Activity启动模式。

    Android开发中Activity属性设置小结

    Activity是Android组件中最基本也是最为常见用的四大组件之一,在 android开发中 ,运用极为广泛,作为初学者需要熟练掌握,下例为Activity属性常用设置。 android:allowTaskReparenting 是否允许activity更换从属...

    Android开发艺术探索

    第1章 Activity的生命周期和启动模式 / 1 1.1 Activity的生命周期全面分析 / 1 1.1.1 典型情况下的生命周期分析 / 2 1.1.2 异常情况下的生命周期分析 / 8 1.2 Activity的启动模式 / 16 1.2.1 Activity的...

    新版Android开发教程.rar

    Android Android Android Android 开发背景 � 计算技术、无线接入技术的发展,使嵌入式系统逐渐有能力对桌面系统常规业务进行支持。 � 谷歌长期以来奉行的移动发展战略:通过与全球各地的手机制造商和移动运营商...

    Android开发中Activity创建跳转及传值的方法

    今天所介绍的就是Android开发中的四大组件之一:Activity,其他那三大组件以后再进行介绍。说道Android中的Activity,如果你做过iOS开发的话,Activity类似于iOS中的ViewController(视图控制器)。在应用中能看到的...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    第1章 Activity的生命周期和启动模式 1 1.1 Activity的生命周期全面分析 1 1.1.1 典型情况下的生命周期分析 2 1.1.2 异常情况下的生命周期分析 8 1.2 Activity的启动模式 16 1.2.1 Activity的LaunchMode 16 ...

    Android-一个封装了启动模式的Fragment便捷使用库方便构建单Activity多Fragment轻量级框架

    一个封装了启动模式的Fragment便捷使用库,方便构建单Activity 多Fragment轻量级框架

    Android开发与应用——张荣,原书配套课件

    这是Android开发与应用,原书配套的课件,作者张荣,目录如下。 第1章 Android简介 1.1 手机操作系统 1.2 Android起源 1.3 Android特征 1.4 Android体系结构 1.4.1 应用层 1.4.2 应用框架层 1.4.3 ...

    android开发艺术探索高清完整版PDF

    目录 第1章 Activity的生命周期和启动模式 / 1 1.1 Activity的生命周期全面分析 / 1 1.1.1 典型情况下的生命周期分析 / 2 1.1.2 异常情况下的生命周期分析 / 8 1.2 Activity的启动模式 / 16 1.2.1 Activity的...

Global site tag (gtag.js) - Google Analytics