android activity的四种启动模式

2019-04-14 20:05发布

*启动模式一共有四种,分别是 standard、singleTop、
singleTask 和 singleInstance,可以在 AndroidManifest.xml 中通过给标签指定
android:launchMode属性来选择启动模式*
  • standard
    android 的默认启动模式,每当启动一个新的activity 他就会在activity的返回栈中创建一个新的实例,并处于栈顶的位置。比如FirstActivity在button的点击事件中再次启动一个FirstActivity,这时候再返回栈中其实有两个activity的实例。且都是FirstActivity. 这就是standard启动模式。
这里写图片描述
  • singleTop
    在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用
    它,不会再创建新的活动实例。 即如果你在FirstActivity中再启动FirstActivity,则他就直接使用FirstActivity,而不会再创建一个新的FirstActivity实例。那么 如果你是FirstActivity启动secondActivity,然后再在secondActivity里启动FirstActivity的话,他还是会创建一个新的FirstActivity实例。
    这里写图片描述
  • singleTask
    当活动的启动模式指定为 singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
    这里写图片描述
  • singleInstance
    当你使用这种启动模式的时候,系统会指定为这个活动启用一个新的返回栈来管理这个活动。这样做的意义在哪里呢 ?
想象以下场景,假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面三种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance 模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。 修改 AndroidManifest.xml中 SecondActivity的启动模式: ".SecondActivity" android:launchMode="singleInstance" > "com.example.activitytest.ACTION_START" /> "android.intent.category.DEFAULT" /> "com.example.activitytest.MY_CATEGORY" /> 我们先将 SecondActivity 的启动模式指定为 singleInstance,然后修改 FirstActivity 中 onCreate()方法的代码: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("FirstActivity", "Task id is " + getTaskId()); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.first_layout); Button button1 = (Button) findViewById(R.id.button_1); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent); } }); } 在 onCreate()方法中打印了当前返回栈的 id。然后修改 SecondActivity中 onCreate()方法 的代码: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("SecondActivity", "Task id is " + getTaskId()); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.second_layout); Button button2 = (Button) findViewById(R.id.button_2); button2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SecondActivity.this, ThirdActivity.class); startActivity(intent); } }); } 同样在 onCreate()方法中打印了当前返回栈的 id,然后又修改了按钮点击事件的代码, 用于启动 ThirdActivity。最后修改 ThirdActivity中 onCreate()方法的代码: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("ThirdActivity", "Task id is " + getTaskId()); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.third_layout); } logCat打印结果如下 这里写图片描述 可以看到,FirstActivity和ThirdActivity是在同一个返回栈中的都是19,而secondActivity则在20这个栈里面。说明它启动了一个新的返回栈。这时候你在ThirdActivity按下返回键,可以看到是返回的firstActivity的。然后再按返回键则返回了secondActivity。这是为什么呢?
当在ThirdActivity的界面按下 Back 键,ThirdActivity会从返回栈中出栈,那么 FirstActivity 就成为栈顶活动显示在界面上,因此也就出现了从 ThirdActivity 直接返回到 FirstActivity 的情况。然后在FirstActivity界面再次按下 Back键,这时当前的返回栈已经空了,于是就显示了另一个返回栈的栈顶活动,即 SecondActivity。最后再次按下 Back 键,这时所有返回栈都已
经空了,也就自然退出了程序 这里写图片描述