您的位置:首页 > 移动开发 > Android开发

Android启动模式之lunchMode

2015-10-27 21:56 483 查看
  大家看这个帖子之前先了解一下task,taskAffinity属性。

  在开发一个项目时,会遇到多个页面跳转的问题,在Android中通常会使用启动模式来处理页面跳转。Activity的启动模式有四种:

  standard

  singleTop

  singleTask

  singleInstance

  接下来将详细介绍这四种模式

standard模式

  standard模式是最基本的模式,也是默认的模式,它不需要在AndroidManifest文件设置。其主要的特点是每次通过Intent打开Activity,都会新建一个该Activity实例放入发出该intent的task的顶部。我们可以通过一个实例来验证:

  

public class FirstActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
TextView tv_task= (TextView) findViewById(R.id.tv_task);
tv_task.setText(this.toString());
Button btn_first= (Button) findViewById(R.id.btn_first);
btn_first.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(FirstActivity.this,FirstActivity.class));
}
});
}
}


  点击button将打开一个FristActivity实例,TextView显示该实例的信息。

  


  


  


  从显示的信息可以看出创建出了三个不同的FirstActivity实例。当我们按返回键时会从当前实例返回到上一个实例。

  这是standard模式的工作方式,不管有没有已存在的实例,都会重新创建一个新的实例放在相应task的栈顶。

  上边是在同一个应用中打开,那么我们现在再来看看跨应用的情况:

  Android5.0之前和之后(包括Android5.0)处理方式是不一样的,在Android5.0之前跨应用和在同一个应用处理方式是一样的。但是在Android5.0之后跨应用之间启动Activity,会创建一个新的Task,新生成的Activity就会放入刚创建的Task中。如图:



  此时我们打开Android任务管理器,可以看到两个独立的任务:

  


  

singleTop

  我们还是先看看上边的实例,我们在AndroidManifest文件中给FirstActivity设置lunchMode

  

<activity android:name=".ui.FirstActivity"
android:label="FirstActivity"
android:launchMode="singleTop"/>


运行程序会得到以下结果:

  


  


  


  没错这次三个的编号是一样的,也就是说这是一个实例。当按back键时直接退出应用程序。

  这是因为当我们把FirstActivity的lunchMode设置成singleTop之后,在每一次启动FirstActivity时,系统判断相应的task的栈顶是不是FirstActivity实例,如果是就不在创建新的实例并调用其OnNewIntent方法,如果不是则新建实例并且放在task栈顶!

  其实可以看出:standard和singleTop基本上是一样的(包括跨应用),使用singleTop的Activity也可以创建很多个实例。唯一不同的是,如果调用的目标Activity已经位于调用者的Task的栈顶,则不创建新实例,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法

  

singleTask

  singleTask和之前的standard、singleTop有很大的不同。使用singleTask的Activity在系统中只会存在一个实例。

  在同一个应用中如果系统中不存在singleTask Activity的实例,那么就需要创建这个Activity的实例,并且将这个实例放入和调用者相同的Task中并位于栈顶。

  


  如果singleTask Activity实例已然存在,那么在Activity回退栈中,所有位于该Activity上面的Activity实例都将被销毁掉(销毁过程会调用Activity生命周期回调),这样使得singleTask Activity实例位于栈顶。与此同时,Intent会通过onNewIntent传递到这个SingleTask Activity实例。

  


  

  跨应用启动Activity时,如果系统中不存在singleTask Activity的实例,那么讲创建一个新的Task,然后创建SingleTask Activity的实例,将其放入新的Task中。如果singleTask Activity所在的应用进程存在,但是singleTask Activity实例不存在,那么从别的应用启动这个Activity,新的Activity实例会被创建,并放入到所属进程所在的Task中,并位于栈顶位置。更复杂的一种情况,如果singleTask Activity实例存在,从其他程序被启动,那么这个Activity所在的Task会被移到顶部,并且在这个Task中,位于singleTask Activity实例之上的所有Activity将会被正常销毁掉。如果我们按返回键,那么我们首先会回退到这个Task中的其他Activity,直到当前Task的Activity回退栈为空时,才会返回到调用者的Task。

singleInstance

  这个模式和singleTask差不多,因为他们在系统中都只有一份实例。唯一不同的就是存放singleInstance Activity实例的Task只能存放一个该模式的Activity实例。如果从singleInstance Activity实例启动另一个Activity,那么这个Activity实例会放入其他的Task中。同理,如果singleInstance Activity被别的Activity启动,它也会放入不同于调用者的Task中。

  


  

  这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。建议谨慎使用

  简单的介绍了一下四种启动模式,之后会介绍Intent Flags与启动模式结合使用的情况。

  参考链接:Understand Android Activity’s launchMode: standard, singleTop, singleTask and singleInstance

        http://droidyue.com/blog/2015/08/16/dive-into-android-activity-launchmode/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: