Android学习之Activity的启动模式
一、引言
很多朋友去面试的时候,可能都会被问到这样一个问题:
请给我详细描述一下Activity的生命周期,及其相关的启动模式。
生命周期我倒是知道一点,启动模式又是个什么玩意?如果你没有事先准备的话,可能会被问个措手不及。那么接下来,就让我带你深入的了解这个知识点。
(关于Activity的生命周期,在之前的文章中已经讲过了,感兴趣的小伙伴点击下面的链接,就可以查询到。)
二、四种启动方式
Activity中一共有四种启动模式,分别为:
- standard 标准启动模式
- singleTop
- singleTask
- singleInstance
它们主要是在AndroidMainifest文件中,通过给activity标签指定android:launchMode属性来设置。
在这里我们要了解一个概念,android是通过返回栈来管理活动的。而栈是一个后进先出的数据结构,所以每当我们创建一个新活动,它都会自动放在栈顶。当我们使用finish()销毁这个活动时,位于栈顶的活动就会出栈,前一个入栈的活动,就会重新出现在栈顶。我们的系统每次都会将栈顶的活动展现给用户。
了解了这些以后,我们来对这四种启动方式深入解析吧~
三、standard
standard是活动默认的启动方式。每当你创建一个新活动,它就会在返回栈中入栈,并处于栈顶的位置。而且它不会管你栈中是否已经存在这个实例,每次启动都会创建一个新的实例。
下面我们进行代码演示分析:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("MainActivity",this.toString()); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this,MainActivity.class)); } }); } }
在这里我们创建了一个按钮,用于在两个MainActivity之间的转跳。如果按照正常的来说,这个MainActivity已经被创建了,我们不管怎么转跳,都不会产生新的实例才对,但是事实并不是这样。我们查看下打印信息。
可以看到,我一共点击了两次按钮,它又重新创建了两个实例。这样你按返回键时,也需要点击三次才可以完全退出。
四、singleTop
了解了standard模式后,你可能会觉得不太合理对吧?为啥我已经存在了,还需要重新创建。但这是系统默认的启动方式,你也可以进行相关的修改。比如这种SingleTop模式。当你的返回栈栈顶已经是该活动,就可以直接进行调用,就不会重新创建新的实例
下面我们进行代码演示:
首先我们在AndroidMainifest文件中,修改其启动模式。
<activity android:name=".MainActivity" android:launchMode="singleTop">
然后我们继续运行这个程序,会发现你不管点击多少次,都不会产生新的实例。因为这时候MainActivity已经处于栈顶了。
但是这种启动方式,还是会存在着一定的问题。我们首先创建一个点击事件,让MainActivity转跳到SecondActivity。
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("MainActivity",this.toString()); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this,SecondActivity.class)); } }); } }
然后再在SecondActivity中,转跳回MainActivity
public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("SecondActivity",this.toString()); setContentView(R.layout.activity_second); findViewById(R.id.button_1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(SecondActivity.this,MainActivity.class)); } }); } }
这时候查看打印信息:
这时候你会发现,它又重新创建了一个MainActivity,这是为什么呢?
其实很简单,因为刚开始MainActivity在栈顶,但当你转跳到另一个界面时,栈顶就会变成SecondActivity,所以这时候会重新创建一个MainActivity。
五、singTask
这个启动方式,就可以很好的解决之前出现的一切问题。因为当你使用这个启动方式,每一次都会在返回栈中检查是否存在该活动的实例,如果发现已存在,那么就会直接调用,并且将这个活动上的所有活动全部出栈。如果没有发现,那么就会创建一个新的实例。
下面进行代码演示:
首先我们在MainActivity中添加一个OnRestart方法:
@Override protected void onRestart() { super.onRestart(); Log.d("MainActivity","OnRestart"); }
在SecondActivity中添加一个OnDestroy方法:
@Override protected void onDestroy() { super.onDestroy(); Log.d("SecondActivity","OnDestroy"); }
执行后发现:
从这个打印信息我们可以得出,当刚开始启动时,MainActivity处于栈顶,转跳到SecondActivity以后,MainActivity就在底下了,这时候再返回MainActivity,就会将SecondActivity出栈,并重新调用MainActivity,也不要创建新的实例。按一次返回键就可以退出了。
六、SingInstance
这个启动方式就厉害了。它会给你这个活动创建一个新的返回栈,单独保存。这样有什么意义呢?这样可以实现其他程序和我们的程序,共享这个活动的实例。
下面进行代码演示:
首先我们将SecondActivity的启动方式改为singInstance
然后在MainActivity中添加一个打印信息:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("MainActivity","Task id is" + getTaskId()); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this,SecondActivity.class)); } }); }
在SecondActivity中也添加一个打印信息:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("SecondActivity","Task id is" + getTaskId()); setContentView(R.layout.activity_second);
在ThirdActivity中也添加一个打印信息:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("ThirdActivity","Task id is" + getTaskId()); setContentView(R.layout.activity_third);
运行以后输出打印信息:
可以看出MainActivity和ThirdActivity在一个栈中,SecondActivity在另一个栈中。
但是当我们按下返回键以后,会发现直接从ThirdActivity直接返回到MainActivity,然后再按一下返回,又会返回到SecondActivity,最后按一下back才能退出。为什么会出现这种情况呢?其实很简单,因为MainActivity和ThirdActivity处于一个栈中,当ThirdActivity出栈后,MainActivity就会出现在栈顶。等MainActivity出栈后,这个栈就空了,所以调用另一个栈。也就是SecondActivity所在的栈。最后按一下返回,所以的栈都空了,所以退出程序。
七、小结
Activity的四种启动方式就先讲到这里吧。我觉得整个文章还是比较好理解的,而且所有的步骤都是有代码演示,也比较的清晰。最后希望这篇文章能够帮助到大家,一起共同进步呀!
- 【Android学习入门】Android中activity的启动模式
- 【Android学习】之Activity的启动模式
- Android开发笔记----Activity再学习(生命周期、启动模式、intent-filter)
- Android学习第一篇——Activity的启动模式
- Android学习历程--Activity的四种启动模式
- 微子学习Android之Activity启动模式
- [Android新手学习笔记09]-活动Activity启动模式
- android学习之-activity的启动模式
- Android学习-Android中Activity启动模式详解
- Android学习:Activity四种启动模式
- 《android 学习》二、Activity的四种启动模式
- Android(java)学习笔记225:Activity与Task的4种启动模式
- Androidx学习笔记(52)--- Activity的四种启动模式
- 【幻化万千戏红尘】qianfeng-Android-Day05-Activity生命周期,Actitity的启动模式基础学习:
- Android学习历程--Activity的四种启动模式
- Android 基础学习——Activity四种启动模式
- Android Activity四种启动模式简单介绍,学习记录。
- Android学习之Activity的四种启动模式与特点
- Android开发学习之路--Activity之四种启动模式
- android 学习activity生命周期和启动模式