• Activity的四种加载模式


    在多Activity开发中,有可能是自己应用之间的Activity跳转,也有可能夹带其他应用的可复用的Activity,可能会希望跳转到原来某个Activity实例,而不产生大量重复的Activity。这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。

    Activity有四种加载模式,分别为:

    1、standard:标准模式(默认模式),一调用startActivity()方法就会产生一个新的实例。

    2、singleTop:如果Activity实例位于栈顶,就不产生新的实例,直接使用栈顶的实例,否则,就会产生一个新的实例。

    例如:现在Task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动Intent,如果D是 “standard”模式的,则生成D的一个新实例,栈状态为A-B-C-D-D。如果D是singleTop模式的话,则不会生成D的新实例,栈状态仍为A-B-C-D。如果这时候给B发Intent的话,不管B的launchMode是“standard”还是“singleTop”,都会生成B的新实例,栈状态变为A-B-C-D-B。

    3、singleTask:每次调用都会使用这个实例,不会去产生新的实例了。

    4、singleInstance:跟singleTask模式基本上是一样,只有一个区别:在这个模式下的Activity实例与其他Activity处在不同的Task中,此实例所处的Task中只能有这个Activity实例,不能有其他的实例。

    如何设置Activity的加载模式?

    加载模式可以在清单文件AndroidManifest.xml中的<activity>的launchMode属性进行配置。

    <activity
                android:name="ActivityOne"
                android:label="@string/app_name"
                android:launchMode="standard">
    </activity>

    四种加载模式的区别(示例说明):

    1standard模式,标准模式,也就是默认模式,不需要在launchMode属性配置。

    /**
     * 默认(standard)加载模式
     * 
     * @author Harvey
     */
    public class ActivityOne extends Activity implements OnClickListener
    {
        private TextView textView;// 显示文本
        private Button button;
        
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            textView = (TextView) findViewById(R.id.textView);
            button = (Button) findViewById(R.id.button);
            button.setText("go to ActivityOne");
            button.setOnClickListener(this);
            textView.setText(this + "");
        }
        
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(ActivityOne.this, ActivityOne.class);// 跳转
            startActivity(intent);
        }
    }

     清单文件如下:

    <activity android:name="ActivityOne"
              android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
    </activity>

    经过多次点击按钮后,发现每次在界面上显示hash code值都不同,证明每次点击按钮都创建了该Activity的新实例。接着点击返回键,可以看到是按照刚才创建Activity实例的倒序依次出现,类似退栈的操作,而刚才操作跳转按钮的过程是压栈的操作。

    2singleTop模式,singleTop和standard模式都会将Intent发送新的实例(而后两种模式如果已经有了实例,就不会发送到新的实例)。不过,singleTop要求如果创建Intent的时候栈顶已经有要创建的Activity的实例,则将Intent发送给该实例,而不发送给新的实例。

    /**
     * singleTop模式
     * 
     * @author Harvey
     */
    public class ActivityOne extends Activity implements OnClickListener
    {
        private TextView textView;// 显示文本
        private Button button;
        
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            textView = (TextView) findViewById(R.id.textView);
            button = (Button) findViewById(R.id.button);
            button.setText("go to ActivityOne");
            button.setOnClickListener(this);
            textView.setText(this + "");
        }
        
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(ActivityOne.this, ActivityOne.class);// 跳转
            startActivity(intent);
        }
    }

    清单文件如下:

    <activity
                android:name="ActivityOne"
                android:label="@string/app_name"
                android:launchMode="singleTop">
                <intent-filter>
                    <action
                        android:name="android.intent.action.MAIN" />
                    <category
                        android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
    </activity>

    点击Button按钮数次后,发现都是相同的Activity实例,因为该实例在栈顶,所有不会创建新的实例。如果点击返回键,将退出应用。singleTop模式,可用来解决栈顶多个重复相同的Activity的问题。

    如果A-Activity跳转到B-Activity,再跳转到A-Activity,就和standard模式一样了,在B-Activity跳转到A-Activity的时候就会创建A-Activity的新实例,因为当时的栈顶不是A-Activity实例。

    ActivityOne.java

    /**
     * singleTop模式
     * 
     * @author Harvey
     */
    public class ActivityOne extends Activity implements OnClickListener
    {
        private TextView textView;// 显示文本
        private Button button;
        
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            textView = (TextView) findViewById(R.id.textView);
            button = (Button) findViewById(R.id.button);
            button.setText("go to ActivityTwo");
            button.setOnClickListener(this);
            textView.setText(this + "");
        }
        
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(ActivityOne.this, ActivityTwo.class);// 跳转
            startActivity(intent);
        }
    }

    ActivityTwo.java

    public class ActivityTwo extends Activity implements OnClickListener
    {
        private TextView textView;//显示文本
        private Button button;
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            textView = (TextView) findViewById(R.id.textView);
            button = (Button) findViewById(R.id.button);
            button.setText("go to ActivityOne");
            button.setOnClickListener(this);
            textView.setText(this + "");
        }
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(ActivityTwo.this, ActivityOne.class);//跳转
            startActivity(intent);
        }
    }

    清单文件如下:

    <activity
                android:name="ActivityOne"
                android:label="@string/app_name"
                android:launchMode="singleTop">
                <intent-filter>
                    <action
                        android:name="android.intent.action.MAIN" />
                    <category
                        android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
    </activity>
    <activity
                android:name="ActivityTwo"
                android:label="@string/app_name">
    </activity>

    ActivityOne使用singleTop加载模式,ActivityTwo使用默认(standard)加载模式。ActivityOne也是要生成新的实例的,如果把ActivityOne的加载模式改为standard加载模式,结果也是一样。

    3singleTask模式,和后面的singleInstance模式都是只创建一个实例的。

    当Intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例,如果有直接将Intent发送给它。

    把上面singleTop的实例中的ActivityOne的launchMode改为singleTask,ActivityTwo不改动。

    <activity
                android:name="ActivityOne"
                android:label="@string/app_name"
                android:launchMode="singleTask">
                <intent-filter>
                    <action
                        android:name="android.intent.action.MAIN" />
                    <category
                        android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
    </activity>
    <activity
                android:name="ActivityTwo"
                android:label="@string/app_name">
    </activity>

    多次跳转之后,发现Task中始终只有一个ActivityOne实例。

    4singleInstance模式

    将ActivityOne的模式配置为standard模式,将ActivityTwo的模式配置为singleInstance模式。

    ActivityOne.java

    /**
     * singleInstance模式
     * 
     * @author Harvey
     */
    public class ActivityOne extends Activity implements OnClickListener
    {
        private TextView textView;// 显示文本
        private Button button;
        
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            textView = (TextView) findViewById(R.id.textView);
            button = (Button) findViewById(R.id.button);
            button.setText("go to ActivityTwo");
            button.setOnClickListener(this);
            textView.setText(this + "\n" + "task id:" + this.getTaskId());
        }
        
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(ActivityOne.this, ActivityTwo.class);// 跳转
            startActivity(intent);
        }
    }

    ActivityTwo.java

    public class ActivityTwo extends Activity implements OnClickListener
    {
        private TextView textView;// 显示文本
        private Button button;
        
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            textView = (TextView) findViewById(R.id.textView);
            button = (Button) findViewById(R.id.button);
            button.setText("go to ActivityOne");
            button.setOnClickListener(this);
            textView.setText(this + "\n" + "task id:" + this.getTaskId());
        }
        
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(ActivityTwo.this, ActivityOne.class);// 跳转
            startActivity(intent);
        }
    }

    清单文件如下:

    <activity
                android:name="ActivityOne"
                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="ActivityTwo"
                android:label="@string/app_name"
                android:launchMode="singleInstance">
    </activity>

    经过多次的跳转发现ActivityOne和ActivityTwo的task id不相同,表明两个的Acitity不在同一个Task中。ActivityOne的hash code值在每次跳转之后都不同,表明每次跳转后都会创建一个新的ActivityOne实例,ActivityTwo的hash code值每次跳转之后都相同,表明ActivityTwo所在的Task中只有一个ActivityTwo实例。

  • 相关阅读:
    Ubuntu系统下的实用软件推荐
    上传项目到GitHub
    eclipse+fileSyncPlugin+svn+jenkins+tomcat
    js,jq获取元素位置属性及兼容性写法
    清除浮动的几种方法
    sub,dl,dt,排版,横向滚动条,浮动元素居中,box-sizing
    a里面不能嵌套a
    随笔
    自适应屏幕轮播图详解
    tip
  • 原文地址:https://www.cnblogs.com/renqingping/p/launchMode.html
Copyright © 2020-2023  润新知