欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android基础总结篇之二:Activity的四种launchMode

程序员文章站 2024-03-01 21:29:04
我们今天要讲的是activity的四种launchmode。 launchmode在多个activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的activ...

我们今天要讲的是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配置<activity>的android:launchmode属性为以上四种之一即可。

下面我们结合实例一一介绍这四种lanchmode:

1.standard

standard模式是默认的启动模式,不用为<activity>配置android:launchmode属性即可,当然也可以指定值为standard。
我们将会一个activity,命名为firstactivity,来演示一下标准的启动模式。firstactivity代码如下:

package com.scott.launchmode; 
 
import android.app.activity; 
import android.content.intent; 
import android.os.bundle; 
import android.view.view; 
import android.widget.button; 
import android.widget.textview; 
 
public class firstactivity extends activity { 
  @override 
  public void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.first); 
    textview textview = (textview) findviewbyid(r.id.textview); 
    textview.settext(this.tostring()); 
    button button = (button) findviewbyid(r.id.button); 
    button.setonclicklistener(new view.onclicklistener() { 
      @override 
      public void onclick(view v) { 
        intent intent = new intent(firstactivity.this, firstactivity.class); 
        startactivity(intent); 
      } 
    }); 
  } 
} 

我们firstactivity界面中的textview用于显示当前activity实例的序列号,button用于跳转到下一个firstactivity界面。

然后我们连续点击几次按钮,将会出现下面的现象:

android基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchMode
我们注意到都是firstactivity的实例,但序列号不同,并且我们需要连续按后退键两次,才能回到第一个fristactivity。standard模式的原理如下图所示:
android基础总结篇之二:Activity的四种launchMode
如图所示,每次跳转系统都会在task中生成一个新的firstactivity实例,并且放于栈结构的顶部,当我们按下后退键时,才能看到原来的firstactivity实例。

这就是standard启动模式,不管有没有已存在的实例,都生成新的实例。

2.singletop

我们在上面的基础上为<activity>指定属性android:launchmode="singletop",系统就会按照singletop启动模式处理跳转行为。我们重复上面几个动作,将会出现下面的现象:

android基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchMode

我们看到这个结果跟standard有所不同,三个序列号是相同的,也就是说使用的都是同一个firstactivity实例;如果按一下后退键,程序立即退出,说明当前栈结构中只有一个activity实例。singletop模式的原理如下图所示:android基础总结篇之二:Activity的四种launchMode
正如上图所示,跳转时系统会先在栈结构中寻找是否有一个firstactivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。也许朋友们会有疑问,我只看到栈内只有一个activity,如果是多个activity怎么办,如果不是在栈顶会如何?我们接下来再通过一个示例来证实一下大家的疑问。

我们再新建一个activity命名为secondactivity,如下:

package com.scott.launchmode; 
 
import android.app.activity; 
import android.content.intent; 
import android.os.bundle; 
import android.view.view; 
import android.widget.button; 
import android.widget.textview; 
 
public class secondactivity extends activity { 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.second); 
    textview textview = (textview) findviewbyid(r.id.textview); 
    textview.settext(this.tostring()); 
    button button = (button) findviewbyid(r.id.button); 
    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会跳转到secondactivity,secondactivity又会跳转到firstactivity。演示结果如下:

android基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchMode
我们看到,两个firstactivity的序列号是不同的,证明从secondactivity跳转到firstactivity时生成了新的firstactivity实例。原理图如下:
android基础总结篇之二:Activity的四种launchMode
我们看到,当从secondactivity跳转到firstactivity时,系统发现存在有firstactivity实例,但不是位于栈顶,于是重新生成一个实例。

这就是singletop启动模式,如果发现有对应的activity实例正位于栈顶,则重复利用,不再生成新的实例。

3.singletask

在上面的基础上我们修改firstactivity的属性android:launchmode="singletask"。演示的结果如下:

android基础总结篇之二:Activity的四种launchModeandroid基础总结篇之二:Activity的四种launchMode

android基础总结篇之二:Activity的四种launchModeandroid基础总结篇之二:Activity的四种launchMode
我们注意到,在上面的过程中,firstactivity的序列号是不变的,secondactivity的序列号却不是唯一的,说明从secondactivity跳转到firstactivity时,没有生成新的实例,但是从firstactivity跳转到secondactivity时生成了新的实例。singletask模式的原理图如下图所示:
android基础总结篇之二:Activity的四种launchMode
在图中的下半部分是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

这种启动模式比较特殊,因为它会启用一个新的栈结构,将acitvity放置于这个新的栈结构中,并保证不再有其他activity实例进入。

我们修改firstactivity的launchmode="standard",secondactivity的launchmode="singleinstance",由于涉及到了多个栈结构,我们需要在每个activity中显示当前栈结构的id,所以我们为每个activity添加如下代码:

textview taskidview = (textview) findviewbyid(r.id.taskidview); 
taskidview.settext("current task id: " + this.gettaskid()); 

然后我们再演示一下这个流程:
android基础总结篇之二:Activity的四种launchModeandroid基础总结篇之二:Activity的四种launchMode
我们发现这两个activity实例分别被放置在不同的栈结构中,关于singleinstance的原理图如下:android基础总结篇之二:Activity的四种launchMode
我们看到从firstactivity跳转到secondactivity时,重新启用了一个新的栈结构,来放置secondactivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在secondactivity中再次跳转到firstactivity,这个时候系统会在原始栈结构中生成一个firstactivity实例,然后回退两次,注意,并没有退出,而是回到了secondactivity,为什么呢?是因为从secondactivity跳转到firstactivity的时候,我们的起点变成了secondactivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。

如果我们修改firstactivity的launchmode值为singletop、singletask、singleinstance中的任意一个,流程将会如图所示:android基础总结篇之二:Activity的四种launchMode
singleinstance启动模式可能是最复杂的一种模式,为了帮助大家理解,我举一个例子,假如我们有一个share应用,其中的shareactivity是入口activity,也是可供其他应用调用的activity,我们把这个activity的启动模式设置为singleinstance,然后在其他应用中调用。我们编辑shareactivity的配置:

<activity android:name=".shareactivity" android:launchmode="singleinstance"> 
  <intent-filter> 
    <action android:name="android.intent.action.main" /> 
    <category android:name="android.intent.category.launcher" /> 
  </intent-filter> 
  <intent-filter> 
    <action android:name="android.intent.action.single_instance_share" /> 
    <category android:name="android.intent.category.default" /> 
  </intent-filter> 
</activity> 

然后我们在其他应用中这样启动该activity:

intent intent = new intent("android.intent.action.single_instance_share"); 
startactivity(intent); 

当我们打开shareactivity后再按后退键回到原来界面时,shareactivity做为一个独立的个体存在,如果这时我们打开share应用,无需创建新的shareactivity实例即可看到结果,因为系统会自动查找,存在则直接利用。大家可以在shareactivity中打印一下taskid,看看效果。关于这个过程,原理图如下:android基础总结篇之二:Activity的四种launchMode

原文链接:http://blog.csdn.net/liuhe688/article/details/6754323

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。