Android Activity的启动模式(一)

【摘要】 Android Activity的启动模式(一)
Activity的四种LaunchMode
standard:标准模式
standard是系统的默认启动模式,每次启动一个Activity都会重新创建一个实例,不管这个实例是否已经存在。这是一种典型的多实例实现,一个任务栈可以有多个实例,每个实例也可以属于不同的任务栈,在这种模式下,谁启动了这个Activity,…

Android Activity的启动模式(一)

Activity的四种LaunchMode

standard:标准模式

standard是系统的默认启动模式,每次启动一个Activity都会重新创建一个实例,不管这个实例是否已经存在。这是一种典型的多实例实现,一个任务栈可以有多个实例,每个实例也可以属于不同的任务栈,在这种模式下,谁启动了这个Activity,那么这个Activity就运行在谁的Activity所在的栈中。

比如:ActivityA 启动了Activity B(B是标准模式),那么B就会进入到A所在的栈中。

这样就出现一个很容易忽视的问题,当我们用ApplicationContext去启动一个standard模式的Activity时,会出现如下错误:

@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "this is onStart"); mContext = getApplicationContext(); Intent intent = new Intent(this, SecondActivity.class); mContext.startActivity(intent);
}

  
 
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? at android.app.ContextImpl.startActivity(ContextImpl.java:1018) at android.app.ContextImpl.startActivity(ContextImpl.java:994) at android.content.ContextWrapper.startActivity(ContextWrapper.java:403) at com.org.tcl.launchmodetest.MainActivity.onCreate(MainActivity.java:22)

  
 

这是因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context并没有所谓的任务栈,所以这就会报出错误。

解决这个问题的方法很简单,启动这个Activity的时候指定FLAG_ACTIVITY_NEW_TASK标记位,这样在启动这个Activity的时候就会为它创建一个新的任务栈,这就没问题了。

 @Override
 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "this is onCreate"); mContext = getApplicationContext(); Intent intent = new Intent(this, SecondActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent);
 }

  
 

SingleTop:栈顶复用模式

栈顶复用模式,顾名思义,在这种模式下:

1. 如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它得onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息,需要注意的是,这个Activity的onCreate、onStart不会被系统调用,因为它并没有发生改变。

2. 如果新Activity的实例已经存在但是不是位于栈顶,那么新的Activity仍然会被重建

举个例子,假设目前栈内的情况为ABCD,其中ABCD为4个Activity,A在栈底,D在栈顶,那么假设要再次启动D,如果D的启动模式是SingleTop,那么栈内情况还是ABCD,如果D的启动模式是standard,那么栈内情况就变成了ABCDD

SingleTask:栈内复用模式

栈内复用模式,这是一种单实例模式,在这个模式下,只要Activity在一个栈中存在,那么多次启动这个Activity都不会重新创建实例。和SingleTop一样,这个也会调用onNewIntent方法。

具体一点说,当一个具有singletask模式的Activity A请求启动后,系统首先会寻找是否存在A想要的任务栈,如果不存在,就会重新创建一个任务栈,然后创建A的实例并将A放到这个栈中;如果存在A想要的任务栈,这时需要看A是否在栈中有实例存在,如果有实例存在,那么系统会将A调到栈顶并调用它的onNewIntent方法,如果实例不存在,就创建A的实例并把A压入栈中。

举例说明一下:

  • 比如目前任务栈S1 中的情况是ABC,这个时候Activity D以SingleTask的模式请求启动,其所需要的任务栈是S2,由于S2和D都不存在,所以系统会先创建任务栈S2,然后再创建D的实例将D入栈到S2。
  • 另外一种情况,假设D所需要的任务栈为S1,其他情况如上,那么由于S1已经存在,系统会直接创建D并将其入栈到S1中。
  • 如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,那么根据栈内复用原则,此时D不会创建,系统会把D切换到栈顶并调用其onNewIntent方法,同时由于SingleTask默认具有clearTop的效果,会导致栈内所有在D上面的Activity全部出栈,于是最终S1中的情况变为AD。

SingleInstance:单实例模式

单实例模式:这是一种加强的SingleTask模式,它除了具有SingleTask模式的所有特性之外,还加强了一点,那就是具有此种模式的Activity只能单独的位于一个任务栈中,换句话说,如果Activity A是SingleInstance模式,当A启动后,系统会它创建新的任务栈,然后A独立的在这新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个特性的任务栈已经被系统销毁了。

文章来源: blog.csdn.net,作者:一只会走的糖,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_37213843/article/details/116077495

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享