Activity 的 4 种加载模式

配置 Activity 时可指定 android:launchMode 属性,该属性用于配置该 Activity 的加载模式。该属性支持如下 4 个属性值。

* standard:标准模式,这是默认的加载模式。
* singleTop:Task 栈顶单例模式。
* singleTask:Task 内单例模式。
* singleInstance:全局单例模式。

android 采用 Task 来管理多个 Activity,当我们启动一个应用时,android 就会为之创建一个 Task,然后启动这个应用的入口 Activity(即< intent-filter…/ >中配置为 MAIN 和 LAUNCHER 的 Activity)。

因为 android 并没有为 Task 提供 API,因此开发者无法真正去访问 Task,只能调用 Activity 的 getTaskId()方法来获取它所在的 Task 的ID,事实上,我们可以把 Task 理解成 Activity 栈,Task 以栈的形式来管理 Activity:先启动的 Activity 被放在 Task 栈底,后启动的 Activity 被放在 Task 栈顶。

那么 Activity 的加载模式,就负责管理实例化、加载 Activity 的方式,并可以控制 Activity 与 Task 之间在加载关系。

  1. standard 模式

    每次通过这种模式来启动目标 Activity 时,android 总会为目标 Activity 创建一个新的实例,并将该 Activity 添加到当前 Task 栈中—-这种模式不会启动新的 Task,新的 Activity 将被添加到原有的 Task 中。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
this.setContentView(layout);
// 创建一个TextView来显示该Activity和它所在Task ID
TextView tv = new TextView(this);
tv.setText("Activity为:" + this.toString()
+ "\n" + ",Task ID为:" + this.getTaskId());
Button button = new Button(this);
button.setText("启动MainActivity");
// 添加TextView和Button
layout.addView(tv);
layout.addView(button);
// 为button添加事件监听器,当单击该按钮时启动MainActivity
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建启动MainActivity的Intent
Intent intent = new Intent(MainActivity.this
, MainActivity.class);
startActivity(intent);
}
});
}
}

运行该程序,多次单击程序界面上的“启动 MainActivity”按钮,程序将会不断启动新的 MainActivity 实例(不同 Activity 实例的 hashCode 值有差异),但它们所在的 Task ID

总是相同的—-这表明这种加载模式不会使用全新的 Task。

当用户单击手机的“返回”键时,系统将会“逐一”从 Activity 栈顶删除 Activity 实例。

  1. singleTop 模式

这种模式与 standard 模式基本相似,但是有一点不同:当将要启动的目标 Activity 已经位于 Task 栈顶时,系统不会重新创建目标 Activity 的实例,而是直接复用已有的 Activity 实例。

如果将上面实例中 MainActivity 的加载模式改为 singlerTop,那么无论用户单击多少次按钮,界面上的程序都不会有任何变化。

如果将要启动的目标 Activity 没有位于 Task 栈顶,此时系统会重新创建目标 Activity 的实例,并将它加载到 Task 栈顶—-此时与 standard 模式完全相同。

  1. singleTask 模式

采用这种加载模式的 Activity 在同一个 Task 内只有一个实例,当系统采用 singleTask 模式启动目标 Activity 时,可分为如下三种情况。

  • 如果将要启动的目标 Activity 不存在,系统将会创建目标 Activity 的实例,并将它加入 Task 栈顶。
  • 如果将要启动的目标 Activity 已经位于 Task 栈顶,此时与 singleTop 模式的行为相同。
  • 如果将要启动的目标 Activity 已经存在、但没有位于 Task 栈顶,系统将会把位于该 Activity 上面的所有 Activity 移出 Task 栈,从而使得目标 Activity 转入栈顶。

下面的实例示范了上面第三种情况。该实例包含两个 Activity,其中第一个 Activity 上显示文本框和按钮,按钮启动第二个 Activity;第二个 Activity 上显示文本框和按钮,按钮启动第一个 Activity。

第一个 Activity 代码如下。

public class SingleTaskTest extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        LinearLayout layout = new LinearLayout(this);

        layout.setOrientation(LinearLayout.VERTICAL);

        this.setContentView(layout);

        // 创建一个TextView来显示该Activity和它所在Task ID

        TextView tv = new TextView(this);

        tv.setText("Activity为:" + this.toString()

                + "\n" + ",Task ID为:" + this.getTaskId());

        Button button = new Button(this);

        button.setText("启动SecondActivity");

        layout.addView(tv);

        layout.addView(button);

        // 为button添加事件监听器,当单击该按钮时启动SecondActivity

        button.setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent intent = new Intent(SingleTaskTest.this

                        , SecondActivity.class);

                startActivity(intent);

            }

        });
}
  • singleInstance 模式
public class SingleInstanceTest extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
this.setContentView(layout);
// 创建一个TextView来显示该Activity和它所在Task ID
TextView tv = new TextView(this);
tv.setText("Activity为:" + this.toString()
+ "\n" + ",Task ID为:" + this.getTaskId());
Button button = new Button(this);
button.setText("启动SecondActivity");
layout.addView(tv);
layout.addView(button);
// 为button添加事件监听器,当单击该按钮时启动SecondActivity
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SingleInstanceTest.this
, SecondActivity.class);
startActivity(intent);
}
});
}
}

配置该 Activity 的配置片段如下:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="org.yonga.app" >

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name=".SingleInstanceTest"

            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:name=".SecondActivity"

                  android:label="@string/second"

                  android:exported="true"

                  android:launchMode="singleInstance">

            <intent-filter>

                <!-- 指定该Activity能响应Action为指定字符串的Intent -->

                <action android:name="org.yonga.intent.action.YONGA_ACTION" />

                <category android:name="android.intent.category.DEFAULT" />

            </intent-filter>

        </activity>

    </application>

</manifest>
public class MainActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        LinearLayout layout = new LinearLayout(this);

        layout.setOrientation(LinearLayout.VERTICAL);

        this.setContentView(layout);

        // 创建一个TextView来显示该Activity和它所在Task ID

        TextView tv = new TextView(this);

        tv.setText("Activity为:" + this.toString()

                + "\n" + ",Task ID为:" + this.getTaskId());

        Button button = new Button(this);

        button.setText("启动SecondActivity");

        // 添加TextView和Button

        layout.addView(tv);

        layout.addView(button);

        // 为button添加事件监听器,使用隐式Intent启动目标Activity

        button.setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                // 使用隐式Intent启动Second Activity

                Intent intent = new Intent();

                intent.setAction("org.yonga.intent.action.YONGA_ACTION");

                startActivity(intent);

            }

        });

    }
}

Activity 的 4 种加载模式的更多相关文章

  1. Activity有四种加载模式(转)

    Activity有四种加载模式: standard singleTop singleTask singleInstance 在多Activity开发中,有可能是自己应用之间的Activity跳转,或者 ...

  2. 【Android进阶】Activity的四种加载模式

    Activity的四种加载模式: 1.standard :系统的默认模式,一次跳转即会生成一个新的实例.假设有一个activity命名为Act1, 执行语句:startActivity(new Int ...

  3. 区分Activity的四种加载模式

    在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity.可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity. ...

  4. Android学习记录(8)—Activity的四种加载模式及有关Activity横竖屏切换的问题

    Activity有四种加载模式:standard(默认), singleTop, singleTask和 singleInstance.以下逐一举例说明他们的区别: standard:Activity ...

  5. 区分Activity的四种加载模式【转载】

    此文为转载,文章来源:http://marshal.easymorse.com/archives/2950 文章作者:   Marshal's Blog 参考文章:http://blog.csdn.n ...

  6. activity的四种加载模式

    在android里,有4种activity的启动模式,分别为: standard, singleTop, singleTask和singleInstance, 其中standard和singleTop ...

  7. Activity的生命周期与加载模式——Activity的4种加载模式

    配置Activity时可指定android:launchMode属性,该属性用于配置该Activity的加载模式,该属性支持如下4个属性值. standard:标准模式,这是默认的加载模式. sing ...

  8. activity的四种加载模式介绍

      四种加载模式的介绍: a) Standard : 系统默认模式,一次跳转即会生成一个新的实例:    b) SingleTop : 和 standard 类似,唯一的区别就是当跳转的对象是位于栈顶 ...

  9. Activity有四种加载模式:standard(默认), singleTop, singleTask和 singleInstance

    standard:Activity的默认加载方法,即使某个Activity在Task栈中已经存在,另一个activity通过Intent跳转到该activity,同样会新创建一个实例压入栈中.例如:现 ...

随机推荐

  1. 笨鸟先飞之ASP.NET MVC系列之过滤器(06异常过滤器)

    概念介绍 异常过滤器主要在我们方法中出现异常的时候触发,一般我们用 异常过滤器 记录日志,或者在产生异常时做友好的处理 如果我们需要创建异常过滤器需要实现IExceptionFilter接口. nam ...

  2. C基本类型

    C基本类型有: char:8位,可添加修改符signed或是unsigned short:16位,同有singed和unsigned int:32位,同有singed和unsigned long:在3 ...

  3. Java 获取SQL查询语句结果

    step1:构造连接Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnec ...

  4. 学习一门新语言需要了解的基础-12 if和switch对比

    本节内容 是否存在性能差异 使用场景 反汇编对比[付费阅读] 之前初步接触了汇编,然后利用汇编简单了解下函数调用的过程,包括怎么样保护堆栈帧现场和恢复现场.另外做了简单的函数调用参数复制,返回值的传递 ...

  5. hdu 3091 Necklace(状态压缩类似于TSP问题)

    Necklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)Total ...

  6. redis源码分析之发布订阅(pub/sub)

    redis算是缓存界的老大哥了,最近做的事情对redis依赖较多,使用了里面的发布订阅功能,事务功能以及SortedSet等数据结构,后面准备好好学习总结一下redis的一些知识点. 原文地址:htt ...

  7. easyui dialog 中嵌入html页面

    最近使用easyui比较多,这个插件确实很好用.在使用时也遇到了大大小小的问题,好在都一一解决了. 记录一下今天遇到的问题. 目的:用easyui的dialog嵌入一个html页面(html中仍有要执 ...

  8. javascript 可多选的下拉框 multiselect

    首先引用一个写的很好的博客http://www.cnblogs.com/landeanfen/p/5013452.html 我使用的是bootstrap-multiselect,实现功能是 选择下拉框 ...

  9. MySQL服务相关

    1.管理员身份运行cmd方法: 在C:\Windows\System32\cmd.exe右键以管理员身份运行 2.查看MySQL服务选项(路径:任务管理器-服务tab-选中任一服务点击打开服务-进入服 ...

  10. 【机器学习实战】第14章 利用SVD简化数据

    第14章 利用SVD简化数据 SVD 概述 奇异值分解(SVD, Singular Value Decomposition): 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征.从生 ...