Activity的四种启动模式LaunchMode

launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈(后进先出)结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task
Activity一共有以下四种LaunchMode:
1.standard
2.singleTop
3.singleTask
4.singleInstance
我们可以在AndroidManifest.xml配置的Android: LaunchMode属性为以上四种之一即可,如果不配置,默认是standard

1、standard:标准模式,这也是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。被创建的实例的生命周期符合典型情况下的生命周期,它的onCreateonStartonResume都会被调用。该模式不会调用onNewIntent方法
下面用一个例子演示一下standard模式:


public class FirstActivity extends AppCompatActivity {

@Override protected void onCreate(Bundle savedInstanceState) {

 super.onCreate(savedInstanceState);   
 setContentView(R.layout.activity_first);        

// Example of a call to a native method

TextView tv = (TextView) findViewById(R.id.sample_text);  
  
tv.setText(this.toString());
    
Button button = (Button) findViewById(R.id.btn);

button.setOnClickListener(new View.OnClickListener() {            

      @Override            
      public void onClick(View v) {               
            Intent intent = new Intent(FirstActivity.this,FirstActivity.class);                
            startActivity(intent);            
      } 

      @Override
      protected void onNewIntent(Intent intent) {                  
            super.onNewIntent(intent);      
            Log.i("FirstActivity","onNewIntent called");}
    });   

}

}


Activity的四种启动模式LaunchMode_第1张图片
1.png
Activity的四种启动模式LaunchMode_第2张图片
2.png

Activity的四种启动模式LaunchMode_第3张图片
3.png

通过图片可以看到,我们每次点击按钮都新建了不同的FirstActivity实例,并且我们需要连续按后退键两次,才能回到第一个FristActivity。
standard模式的原理如下图所示:

Activity的四种启动模式LaunchMode_第4张图片
standard模式出栈入栈示意图.png

如图所示,每次跳转系统都会在 task中生成一个新的FirstActivity实例,并且放于栈结构的顶部,当我们按下后退键时,才能看到原来的FirstActivity实例。
这就是 standard启动模式,不管栈有没有已存在的实例,都会创建新的实例。
2、 singleTop:栈顶复用模式。在这种模式下,1️⃣如果新的Activity已经位于任务栈的 栈顶,注意是位于栈顶,那么此Activity不会被重新创建,同时它的 onNewIntent方法会被调用,通过此方法的参数我们可以取出当前请求的信息。需要注意的是, onCreateonStartonResume不会被调用,因为它并没有发生改变。2️⃣但是如果新的Activity实例 已存在但没有位于栈顶,那么新的Activity仍然会被重新创建。
1️⃣
我们在上面代码的基础上为指定属性 android:launchMode="singleTop",系统就会按照 singleTop启动模式处理跳转行为。我们重复上面几个动作,将会出现下面的现象:
同时 onNewIntent会被调用,我们可以在 onNewIntent中的形参 Intent intent获取一些数据做一些操作。
 
 
09-19 17:51:27.013 6674-6674/xiaoyong68.com.activitylaunchmode I/FirstActivity: onNewIntent called

Activity的四种启动模式LaunchMode_第5张图片
1.png
Activity的四种启动模式LaunchMode_第6张图片
2.png
Activity的四种启动模式LaunchMode_第7张图片
3.png

我们看到这个结果跟standard有所不同,三个序列号是相同的,也就是说使用的都是同一个FirstActivity实例;如果按一下后退键,程序立即退出,说明当前栈结构中只有一个Activity实例。
singleTop模式的原理如下图所示:

Activity的四种启动模式LaunchMode_第8张图片
singleTop模式出栈入栈示意图..png

正如上图所示,跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。也许朋友们会有疑问,我只看到栈内只有一个Activity,如果是多个Activity怎么办,如果不是在栈顶会如何?2️⃣我们接下来再通过一个示例来证实一下大家的疑问。
我们再新建一个Activity命名为SecondActivity,如下:


public class SecondActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    // Example of a call to a native method
    TextView tv = (TextView) findViewById(R.id.sample_text);
    tv.setText(this.toString());
    Button button = (Button) findViewById(R.id.btn);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
            startActivity(intent);
        }
    });
}

}


然后将FirstActivity中的跳转代码改为:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);

startActivity(intent);


点击FirstActivity中按钮会从FirstActivity跳转到SecondActivity,点击SecondActivity中按钮会从SecondActivity又会跳转到FirstActivity。演示结果如下:

Activity的四种启动模式LaunchMode_第9张图片
屏幕快照 2016-09-19 20.13.51.png
Activity的四种启动模式LaunchMode_第10张图片
屏幕快照 2016-09-19 20.14.03.png
Activity的四种启动模式LaunchMode_第11张图片
屏幕快照 2016-09-19 20.14.14.png

我们看到,两个FirstActivity的序列号是不同的,证明从SecondActivity跳转到FirstActivity时生成了新的FirstActivity实例。原理图如下:

Activity的四种启动模式LaunchMode_第12张图片
屏幕快照 2016-09-19 20.22.12.png

我们看到,当从SecondActivity跳转到FirstActivity时,系统发现存在有FirstActivity实例,但不是位于栈顶,于是重新生成一个实例,这种方式会重新新建, onCreateonStartonResume会被调用,但是 onNewIntent则不会被调用。 值得注意的是,当我们不按SecondAndroid的按钮而直接按back键返回到FirstActivity时,FirstActivity不会重新创建,只是把原来的重新展现,生命周期函数执行如下:onRestart->onStart->onResume->onWindowFocusChanged


09-19 20:31:19.914 14458-14458/xiaoyong68.com.activitylaunchmode I/FirstActivity: onRestart called.

09-19 20:31:19.918 14458-14458/xiaoyong68.com.activitylaunchmode I/FirstActivity: onStart called.

09-19 20:31:19.918 14458-14458/xiaoyong68.com.activitylaunchmode I/FirstActivity: onResume called.

09-19 20:31:19.978 14458-14458/xiaoyong68.com.activitylaunchmode I/FirstActivity: onWindowFocusChanged called.


这就是singleTop启动模式,如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例。
3、singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,系统会回调其onNewIntent方法。具体一点,当一个具有singleTask模式的Activity请求启动后,例如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后把A放到栈中。如果存在A所需要的任务栈,这时需要看A是否在栈中有实例存在,如果有,那么系统就把A调到(在A前面的Activity实例全部出栈)栈顶并调用其onNewIntent方法,如果不存在实例,就创建A的实例并把A压入栈中。

在上面的基础上我们修改FirstActivity的属性android:launchMode="singleTask"。演示的结果如下:

Activity的四种启动模式LaunchMode_第13张图片
FirstActivity1.png

Activity的四种启动模式LaunchMode_第14张图片
SecondActivity1.png

Activity的四种启动模式LaunchMode_第15张图片
FirstActivity2.png

Activity的四种启动模式LaunchMode_第16张图片
SecondActivity2

我们注意到,在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。singleTask模式的原理图如下图所示:
Activity的四种启动模式LaunchMode_第17张图片
屏幕快照 2016-09-19 21.09.05.png

在图中的下半部分是SecondActivity跳转到FirstActivity后的栈结构变化的结果,我们注意到,SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivity时,SecondActivity实例都被迫出栈,下次等FirstActivity跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。
这就是singleTask模式,如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
4、 singleInstance:单实例模式。是一种加强的 singleTask模式,它除了具有 singleTask模式的所有特性外,还加强了一点,那就是此种模式的Activity只能单独地位于一个任务栈中,换句话说,比如Activity A是 singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A独自在这个新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了。

你可能感兴趣的:(Activity的四种启动模式LaunchMode)