Android 活动的启动模式

活动启动有以下四种模式:standard、singleTop、singletask、singleInstance
项目完整代码
https://github.com/Phil-tom/Android-The-First-Line-of-Code/tree/main/Chapter2/ActivityTest

1、standard

standard是活动默认的启动模式,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的新的实例。
每点击一次按钮就会创建一个新的FirstActivity实例,需要按多次Back键才能退出
个人觉得:如果没有在软件中设置返回按钮来返回特定的界面的话,用户体验感会不好
点击BTN1这个按钮,观察日志输出

button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });

每次启动都会创建该活动的一个新的实例。
在这里插入图片描述
在这里插入图片描述

2、singleTop

在启动活动时发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例
在Manifest.xml文件的activity标签下添加

android:launchMode="singleTop"

结果是只会出现一条打印信息,在创建完成以后,点击btn1的按钮也不会有反应
在这里插入图片描述
注意:当FirstActivity并未处于栈顶位置时,再次启动FirstActivity还是会创建新的实例
修改FirstActivity代码
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);

SecondActivity代码

private static final String TAG = "SecondActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: "+this.toString());
        setContentView(R.layout.second_layout);
        Button button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });
    }

结果证明了:当FirstActivity并未处于栈顶位置时,再次启动FirstActivity还是会创建新的实例
在这里插入图片描述

3、singleTask

每次启动该活动时系统会在返回栈中检查是否存在该活动的实例。如果发现已经存在,直接使用该实例,并把这个活动之上的所有活动统统出栈。如果没有发现就会创建一个新的实例。
修改Manifest.xml文件的activity标签下添加

android:launchMode="singleTsk"

FirstActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: "+this.toString());
        setContentView(R.layout.second_layout);
        Button button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "onRestart: ");
    }

SecondActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: "+this.toString());
        setContentView(R.layout.second_layout);
        Button button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

在SecondActivity中启动FirstActivity时,会发现返回栈中已经存在FirstActivity的实例,并且是在SecondActivity的下面,于是,SecondActivity从返回栈中出栈,而FirstActivity成为返回栈中的栈顶活动,只要按一次Back键就可以退出程序。
在这里插入图片描述

4、singleInstance

这种模式的活动会启用一个新的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,解决了共享活动实例的问题。
前三种启动模式做不到,因为每一个应用程序都有自己的返回栈,同一个活动在不同的返回栈中入栈时必然创建了新的实例。
Manifest.xml中

<activity android:name=".SecondActivity"
    android:launchMode="singleInstance">
    <intent-filter>
        <action android:name="com.zzz.activitytest.ACTION_START"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="com.zzz.activitytest.MY_CATEGORY"/>
    </intent-filter>
</activity>

FirstActivity.java

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //打印返回栈的id
        Log.d(TAG, "onCreate: Task id is" + getTaskId());
        setContentView(R.layout.first_layout);
        Button button1 = (Button) findViewById(R.id.button_1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

SecondActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //打印返回栈的id
        Log.d(TAG, "onCreate: Task id is" + getTaskId());
        setContentView(R.layout.second_layout);
        Button button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
                startActivity(intent);
            }
        });
    }

ThirdActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //打印返回栈的id
    Log.d(TAG, "onCreate: Task id is "+getTaskId());
    setContentView(R.layout.third_layout);
}

SecondActivity的返回栈id不同于FirstActivity和ThirdActivity,说明SecondActivity确实放在一个单独的返回栈里,这个栈中只有SecondActivity一个活动。
在这里插入图片描述
当前活动假设是ThirdActivity,按下Back键,回到FirstActivity(这两个活动在同一个返回栈中),再按Back键,这是栈已经空了,于是就显示另一个返回栈的栈顶活动,所以回到SecondActivity,再按Back键,所有栈都空了,退出程序。
在这里插入图片描述
个人觉得这个图片很形象,singleInstance模式示意图
singleInstance模式示意图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值