zoukankan      html  css  js  c++  java
  • Activity 的 4 种加载模式

    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()
                    + "
    " + ",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()
    
                    + "
    " + ",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()
                    + "
    " + ",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()
    
                    + "
    " + ",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);
    
                }
    
            });
    
        }
    }
    
    欢迎关注我的专属博客http://dyleaf.cn/
  • 相关阅读:
    Linux基础命令---nfsstat显示nfs信息
    Linux基础命令----smbclient
    Myeclipse10下载,安装,破解,插件,优化介绍
    MyEclipse常用插件使用教程
    MyEclipse10 中的两种FreeMarker插件的安装与配置
    导入项目名称重复
    append,appendTo和prepend #1daae2
    Java Session超时设置
    jquery刷新页面
    windows不能显示此连接属性。windows management instrumentation (WMI) 信息可能损坏
  • 原文地址:https://www.cnblogs.com/Dyleaf/p/7679831.html
Copyright © 2011-2022 走看看