Android入门之Activity的四种启动模式

纸上得来终觉浅,绝知此事要躬行  --陆游
问渠那得清如许,为有源头活水来  --朱熹

Activity有四种启动模式,在实际的项目中可以根据特定的需求为每个活动设置恰当的启动模式。可以在AndroidManifest.xml的<activity>标签下指定android:launchMode属性来选择启动模式。
android:launchMode的四个加载模式的值如下:
(1)standard:标准模式,这是默认的加载模式
(2)singleTop: Task栈顶单例模式
(3)singleTask: Task栈内单例模式
(4)singleInstance:全局单例模式

(1)standard标准模式,这是Activity默认的启动模式。每当启动一个新的Activity时,它会在Task中入栈并在栈顶位置。
对于使用standard模式,它不在乎此Activity在栈中是否已经存在,每次启动都会创建一个新的Activity实例并入栈。
standard模式的原理图:

通过原理图我们可以了解到,standard模式每次启动一个Activity都会将其入栈,这与接下来的其他模式还是有所不同的(感觉像废话)。

(2)singleTop:栈顶单例模式
通过standard模式我们了解到每次创建一个新的Activity都会入栈,即使栈顶的Activity与新创建的Activity是一样的,这样就有点无聊了。
singleTop是栈顶单例模式,单例说明只会存在一个相同的Activity,栈顶单例说明在栈顶是单例的。当Activity的启动模式指定为singleTop模式时,
在启动Activity时发现栈顶与此Activity相同,则可以直接使用它不会再创建新的活动实例。
singleTop模式的原理图:

通过原理图我们可以了解到,当栈顶是FristActivity时,如果再启动Activity,则会使用原来的Activity,否则是创建新的Activity。
(3)singleTask:栈内单例模式
虽然singleTop解决了栈顶Activity重复问题,但前两种模式都会有重复的Activity在栈中生存,singleTask是在同一个栈中只有一个实例。
singleTask模式下启动Activity会遇到如下三种情况:
1)、栈中如果不存在要启动的Activity,则Activity直接入栈,并在栈顶。
2)、栈中存在要启动的Activity,并且位于栈顶,则类似于singleTop模式。
3)、栈中存在要启动的Activity,并且并不在栈顶,则需要将此Activity上的所有其他Activity都出栈,使得目标Activity在栈顶。
singleTask模式的原理图:

通过原理图我们了解到,在栈中只会存在一个目标Activity,并且在启动此Activity时,此Activity会在栈顶(也是废话)。
(4)singleInstance:全局单例模式
在这种加载模式下,系统保证无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来加载该Activity实例。
当系统采用singleInstance模式启动目标Activity时,可分为如下两种情况。
1)、如果将要启动的目标Activity不存在,系统会创建一个全新的Task,再创建目标Activity实例,并将它加入新的Task栈顶。
2)、如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中,位于哪个Task中,系统都会把该Activity所在的Task转到前台,从而使该Activity显示出来。
singleInstance原理图:
Android入门之Activity的四种启动模式_第1张图片
通过打印TaskID 会发现,FristActivity和ThridActivity有相同的TaskID,而SecondActivity则是有自己单独的TaskID。
启动FristActivity,然后通过Intent跳转到SecondActivity,在SecondActivity中通过Intent跳转到ThirdActivity,但按Back返回键时,
此时会直接从ThirdActivity跳转到FirstActivity,再按Back键会跳转到SecondActivity,会和之前的顺序不一致,因为同一个栈中的会连续的。

FirstActivity代码及布局:
public class FristActivity extends Activity {

    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.out.println("FirstActivity_taskID:"+getTaskId());
        button=(Button)findViewById(R.id.mybutton);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO 自动生成的方法存根  Intent intent=new Intent(FristActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });
    }

}

SecondActivity的代码及布局:
public class SecondActivity  extends Activity{
 
 Button button;
 
 @Override
 public void onCreate(Bundle savedinstancestate)
 {
      super.onCreate(savedinstancestate);
      setContentView(R.layout.activity_second);
      System.out.println("SecondActivity_taskID"+getTaskId());
      button=(Button)findViewById(R.id.secondbutton);
      button.setOnClickListener(new OnClickListener() {
       
       @Override
       public void onClick(View arg0) {
        // TODO 自动生成的方法存根  Intent intent=new Intent(SecondActivity.this,ThirdActivity.class);
        startActivity(intent);
   
       }
      });
     
     
 }

}

在AndroidManifest.xml中的配置:
<activity android:name=".SecondActivity"
                android:launchMode="singleInstance" >
</activity>


ThirdActivity代码及布局:
public class ThirdActivity extends Activity {
    @Override
    public void onCreate(Bundle savedinstancestate)
    {
        super.onCreate(savedinstancestate);
        System.out.println("ThirdActivity_taskID"+getTaskId());
        setContentView(R.layout.activity_third);
    }

}

通过FristActivity跳转到SecondActivity,通过SecondActivity跳转到ThirdActivity,Task_ID如下图:

可以看到FirstActivity和ThirdActivity的Task_ID相同,而SecondActivity拥有自己的Task_ID

你可能感兴趣的:(android)