实例背景:用于四个页面跳转
准备工作
activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <Button        android:id="@+id/Main_Btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="MainActivity to Activity1"/>LinearLayout>

activity1.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".Activity1">    <Button        android:id="@+id/Btn1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Activity1 to Activity2" />LinearLayout>

activity2.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".Activity2">    <Button        android:id="@+id/Btn2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Activity2 to Activity3" />LinearLayout>

activity3.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".Activity3">    <Button        android:id="@+id/Btn3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Activity3 to MainActivity" />LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {         @Override    protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button mBtn1 = (Button) findViewById(R.id.Main_Btn);        mBtn1.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     Intent intent = new Intent(MainActivity.this, Activity1.class);                startActivity(intent);            }        });        Log.v("BootMode", "MainActivity onCreate()    hasCode:" + this.hashCode());    }}

Activity1.java

public class Activity1 extends AppCompatActivity {         @Override    protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);        setContentView(R.layout.activity1);        Button Btn1 = (Button) findViewById(R.id.Btn1);        Btn1.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     Intent intent = new Intent(Activity1.this, Activity2.class);                startActivity(intent);            }        });        Log.v("BootMode", "Activity1 onCreate()    hasCode:" + this.hashCode());    }}

Activity2.java

public class Activity2 extends AppCompatActivity {         @Override    protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);        setContentView(R.layout.activity2);        Button Btn2 = (Button) findViewById(R.id.Btn2);        Btn2.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     Intent intent = new Intent(Activity2.this, Activity3.class);                startActivity(intent);            }        });        Log.v("BootMode", "Activity2 onCreate()    hasCode:" + this.hashCode());    }}

Activity3.java

public class Activity3 extends AppCompatActivity {         @Override    protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);        setContentView(R.layout.activity3);        Button Btn3 = (Button) findViewById(R.id.Btn3);        Btn3.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     Intent intent = new Intent(Activity3.this, MainActivity.class);                startActivity(intent);            }        });        Log.v("BootMode", "Activity3 onCreate()    hasCode:" + this.hashCode());    }}

注意每个Activity都要注册
AndroidManifest.xml
Android之Activity的四种启动模式_第1张图片

1.standard模式

standard模式是默认的启动模式,即标准模式,在不指定启动模式的前提下,系统默认使用该模式启动Activity,每次启动一个Activity都会重写创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。
Android之Activity的四种启动模式_第2张图片
standard模式是Activity的默认启动方式,每启动一个Activity就会在栈顶创建一个新的实例。
Android之Activity的四种启动模式_第3张图片
如上图MainActivity先入栈,然后到Activity1、Activity2最后到Activity3入栈,此时栈顶是Activity3。可以看到hasCode()的值都是不同的,当再点击Activity3 to MainActivity时,重新创建一个新的实例,放于栈顶,此时可以看到栈顶是MainActivity。

2.singleTop-栈顶复用模式

singleTop模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。

情况1
Android之Activity的四种启动模式_第4张图片
配置
AndroidManifest.xml
此时给Activity3设置android:launchMode=“singleTop”
Android之Activity的四种启动模式_第5张图片
修改Activity3的单击事件
Activity3.java
Android之Activity的四种启动模式_第6张图片
结果
Android之Activity的四种启动模式_第7张图片
情况2
Android之Activity的四种启动模式_第8张图片
配置
AndroidManifest.xml
此时给MainActivity设置android:launchMode=“singleTop”
Android之Activity的四种启动模式_第9张图片
将Activity3的单击事件改回来
Activity3.java
Android之Activity的四种启动模式_第10张图片
结果
Android之Activity的四种启动模式_第11张图片
总结
1.当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
2.当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例

3.singleTask-栈内复用模式

在singleTask模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。
Android之Activity的四种启动模式_第12张图片
配置
AndroidManifest.xml
此时给MainActivity设置android:launchMode=“singleTask”
在这里插入图片描述
给每个Activity.java重载onDestroy()函数
如MainActivity.java,其余的 Activity1、 Activity2、 Activity3一样的。

    @Override    protected void onDestroy() {             super.onDestroy();        Log.v("BootMode", "MainActivity onDestroy()");    }

结果
Android之Activity的四种启动模式_第13张图片
当点击Activity3的按钮来启动MainActivity时, Activity1、 Activity2、 Activity3确实被销毁了,调用了onDestroy()函数。当我们从MainActivity进入到Activity1,Activity2再进入到Activity3后,此时栈中有4个Activity实例,并且MainActivity不在栈顶,而在Activity3跳到MainActivity时,并没有创建一个新的MainActivity,而是复用了该实例,并且原来的Activity1、 Activity2、 Activity3出栈了。

总结
singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈
1.如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去。
2.如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例。
2.1如果存在实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onDestroy()方法。
2.2如果不存在该实例,则新建Activity,并入栈。

4.singleInstance-全局唯一模式

该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
Android之Activity的四种启动模式_第14张图片
配置
AndroidManifest.xml
此时给Activity3设置android:launchMode=“singleInstance”
Android之Activity的四种启动模式_第15张图片
修改每个Activity.java中的Log.v()函数

Log.v("BootMode", "MainActivity onCreate()    hasCode:" + this.hashCode()+"   任务栈号:"+this.getTaskId());

在这里插入图片描述
结果
Android之Activity的四种启动模式_第16张图片

5.总结

1.standard模式是Activity的默认启动方式,每启动一个Activity就会在栈顶创建一个新的实例。

2.singleTop模式会判断要启动的Activity实例是否位于栈顶,如果位于栈顶则直接复用,否则创建新的实例。

3.singleTask模式下每次启动该Activity时,系统首先会检查栈中是 否存在当前Activity实例,如果存在则直接使用,并把当前 Activity之上的所有实例全部出栈。

4.singleInstance模式会启动一个新的任务栈来管理Activity实例,无 论从哪个任务栈中启动该Activity,该实例在整个系统中只有一
个。

更多相关文章

  1. android 图片自动切换
  2. 【转】android 图片自动切换
  3. android 背景图片
  4. android图片切换ImageSwichter的动画切换效果
  5. Android中TextView中加图片,超链接,部分字或者背景变色。。。不断
  6. Java语言程序设计(六)对话框应用实例及随机数的产生
  7. Android 高级进阶之深入剖析四大启动模式
  8. vscode是什么?vscode实例用法汇总

随机推荐

  1. android开发学习笔记(2)android的基本介绍
  2. ArcGIS for Android 支持模拟器开发
  3. Android 5.0之应用中实现材料设计—Mater
  4. Android XML解析学习——Dom方式
  5. Android动态加载外部jar包及jar包中图片
  6. Android 开发新方向 Android Wear ——概
  7. Android Alarm驱动源代码分析(Alarm.c)
  8. android手电筒原理
  9. 70个具有商业实战性的精品Android源码
  10. android Pull解析复杂XML 转