Android四大组件——Activity——Activity的启动模式
Activity有四种启动模式:,singleTop,singleTask,singleInstance.
可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式。
standard:默认启动模式
standard是Activity默认的启动模式,在不进行显示指定的情况下,所有Activity都会自动使用这种启动模式。
Android是用返回栈来管理Activity的,在standard模式下,每当启动一个新的Activity,它就会入返回栈中,并处于栈顶的位置。
对于这种模式的Activity,系统不会在乎该Activity是否已经在返回栈中存在,每次启动都会创建一个该Activity的实例。
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class FirstActivity extends AppCompatActivity { private static final String TGA = "FirstActivity"; private Button btn_first; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); Log.d(TGA,"onCreate()"+this.toString()); initView(); initListener(); } private void initListener() { btn_first.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this,FirstActivity.class); startActivity(intent); } }); } private void initView() { btn_first = findViewById(R.id.btn_first); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TGA,"onDestroy()"+this.toString()); } }
上述代码为:在FirstActivity的基础上启动FirstActivity.这没啥意义,只是为了演示standard模式。这里我们点击四下按钮,并将该Activity打印出来。
日志信息:
可以看到每一次点击都创建了新的实例在返回栈中。栈是先进后出的数据结构。如下图:
现在返回栈中有这么四个实例,现在我按下返回键,@a641637会首先出栈,然后是@8d8a58b,@9d24af9,最后是@5a89e59,这样才退出了程序。
看看日志:
上面为创建Activity时的顺序,红框内的为销毁Activity时的顺序。
很直白的看到了该模式的特点:每一次启动Activity都会创建新的实例,入栈。创建多少个Activity就要点击多少下返回键才能退出。
SingleTop:
你可能觉得standard模式不太合理,Activity明明已经在栈顶了,再次启动时却还能创建一个新的实例。
现在我们来看看SingleTop模式。
它会判断栈顶是否为该Activity,如果是,则直接使用。不是,则创建新的该Activity。
使用场景:一般来说,为了保证只有一个任务,而不被创建多个,所以需要这种模式。如:浏览器的书签,应用的通知推送。
修改为SingleTop模式:‘
<activity android:name=".FirstActivity" android:launchMode="singleTop"> //启动模式 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
这样之后,我们再次多次点击FirstActivity中的启动按钮。只会创建一个Activity的实例。
因为该FirstActivity已经位于栈顶,再次点击使其启动FirstActivity,则可以直接使用。
日志信息如下:
只需按一次返回键就可以退出程序。
现在我们对FirstActivity进行修改。
FirstActivity:
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class FirstActivity extends AppCompatActivity { private static final String TGA = "FirstActivity"; private Button btn_first; private Button btn_second; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); Log.d(TGA,"onCreate()"+this.toString()); initView(); initListener(); } private void initListener() { btn_first.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this,FirstActivity.class); startActivity(intent); } }); btn_second.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this,SecondActivity.class); startActivity(intent); } }); } private void initView() { btn_first = findViewById(R.id.btn_first); btn_second = findViewById(R.id.btn_second); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TGA,"onDestroy()"+this.toString()); } }
界面效果:

SecondActivity:
package com.java.androidstudy; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class SecondActivity extends AppCompatActivity { private static final String TGA = "SecondActivity"; private Button btn_first; private Button btn_second; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Log.d(TGA,"onCreate()"+this.toString()); initView(); initListener(); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TGA,"onDestroy()"+this.toString()); } private void initListener() { btn_first.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SecondActivity.this,FirstActivity.class); startActivity(intent); } }); btn_second.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SecondActivity.this,SecondActivity.class); startActivity(intent); } }); } private void initView() { btn_first = findViewById(R.id.btn_first); btn_second = findViewById(R.id.btn_second); } }
界面效果:

现在FirstActivity的启动模式是SingleTop,而SecondActivity的启动模式是standard.
运行程序后:
首先创建了FirstActivity的实例,日志如下:
然后点击跳转到第二个界面,日志如下:
可以看到,创建了SecondActivity的实例,此刻栈顶是SecondActivity@1a0ef8f。现在返回栈中位置如下图:
我们点击跳转到第一个页面:
因为栈顶是SecondActivity@1a0ef8f,所以新增了一个FirstActivity的实例。
此刻返回栈如下:
现在我们退出程序需要按三下返回键。
完整日志如下:

SingleTask:
每次启动Activity时,该模式会检查栈中是否存在该Activity的实例,
如果存在会让该Activity之上的所有其她Activity统统出栈,
如果没有就会创建一个新的Activity实例。
首先修改AndroidManifest.xml中的FirstActivity的启动模式
<activity android:name=".FirstActivity" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
此刻FirstActivity的启动模式为SingleTask,SecondActivity的启动模式为standard。
在启动FirstActivity时,应在返回栈中检查是否已经存在该Activity,若存在,则让该Activity之上的所有Activity出栈。这种情况下,FirstActivity是从不可见没有焦点的停止状态重新位于栈顶,应会执行onRestart()方法。在FirstActivity中重写onRestart()方法,并打印信息。
现在我先点击三下第一个按钮,再点击第二个按钮。
日志信息如下:
可以看到此刻返回栈中应如下:
此刻我再次点击第一个按钮,日志信息打印如下:
可以看到SecondActivity全部出栈,FirstActivity中执行了onRestart()方法重新成为栈顶。出栈顺序为先销毁上面最近的Activity,待上面的Activity是栈顶后,先onRestart(),再销毁栈顶。
SingleInstance:指定为singleInstance模式的Activity会启动一个新的返回栈来管理这个Activity,
现在修改FirstActiviyt的启动模式为standard,SecondActivity的启动模式是singleInstance。
启动模拟器:
点击一下第一个按钮,再点击一下第二个按钮,再点击一下第一个按钮。
日志如下:
此刻537的返回栈在538的上面,销毁时,537全部销毁完,才轮到538。如下图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程