欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Android開發(fā)中Activity的四種launchMode

 更新時(shí)間:2016年03月08日 15:23:24   作者:liuhe688  
這篇文章主要介紹了Android開發(fā)中Activity的四種launchMode,launchMode主要用于控制多個(gè)Activity間的跳轉(zhuǎn),需要的朋友可以參考下

Activity棧主要用于管理Activity的切換。當(dāng)使用Intent跳轉(zhuǎn)至某個(gè)目標(biāo)Activity,需要根據(jù)目標(biāo)Activity的加載模式來加載。

Activity一共有以下四種launchMode:

1.standard:默認(rèn),每次使用Intent跳轉(zhuǎn)到目標(biāo)Activity時(shí)都創(chuàng)建一個(gè)新的實(shí)例。壞處是每次進(jìn)入都要?jiǎng)?chuàng)建新的實(shí)例,執(zhí)行OnCreate方法。

201638150942001.jpg (1240×930)

2.singleTop:如果要跳轉(zhuǎn)的目標(biāo)Activity正好在task的頂部(說明當(dāng)前肯定不在目標(biāo)task里,例如我在微信首頁,然后想使用Intent跳轉(zhuǎn)到InnoXYZ應(yīng)用的首頁,那么加入InnoXYZ首頁正好在InnoXYZ的task頂部,就直接跳轉(zhuǎn)而不會(huì)創(chuàng)建實(shí)例),那么就直接跳轉(zhuǎn)過去而不會(huì)創(chuàng)建新的。(例子,當(dāng)前在Home Screen, 收到一條微信首頁的推送,而此時(shí)task棧里的微信task里的Activity棧里的最頂部正好就是微信首頁,那么點(diǎn)擊推送就直接進(jìn)入該實(shí)例而不會(huì)創(chuàng)建新的實(shí)例)

201638151101876.jpg (1240×930)

3.singleTask:會(huì)在一個(gè)新的task中產(chǎn)生這個(gè)實(shí)例,以后每次調(diào)用都會(huì)使用這個(gè),不會(huì)去產(chǎn)生新的實(shí)例了。

4.singleInstance:是其所在棧的唯一activity,它會(huì)每次都被重用。

launchMode在多個(gè)Activity跳轉(zhuǎn)的過程中扮演著重要的角色,它可以決定是否生成新的Activity實(shí)例,是否重用已存在的Activity實(shí)例,是否和其他Activity實(shí)例公用一個(gè)task里。這里簡(jiǎn)單介紹一下task的概念,task是一個(gè)具有棧結(jié)構(gòu)的對(duì)象,一個(gè)task可以管理多個(gè)Activity,啟動(dòng)一個(gè)應(yīng)用,也就創(chuàng)建一個(gè)與之對(duì)應(yīng)的task。

我們可以在AndroidManifest.xml配置<activity>的android:launchMode屬性為以上四種之一即可。
下面我們結(jié)合實(shí)例一一介紹這四種lanchMode:
1.standard
standard模式是默認(rèn)的啟動(dòng)模式,不用為<activity>配置android:launchMode屬性即可,當(dāng)然也可以指定值為standard。
我們將會(huì)一個(gè)Activity,命名為FirstActivity,來演示一下標(biāo)準(zhǔn)的啟動(dòng)模式。FirstActivity代碼如下:

standard模式是默認(rèn)的啟動(dòng)模式,不用為<activity>配置android:launchMode屬性即可,當(dāng)然也可以指定值為standard。
我們將會(huì)一個(gè)Activity,命名為FirstActivity,來演示一下標(biāo)準(zhǔn)的啟動(dòng)模式。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用于顯示當(dāng)前Activity實(shí)例的序列號(hào),Button用于跳轉(zhuǎn)到下一個(gè)FirstActivity界面。
然后我們連續(xù)點(diǎn)擊幾次按鈕,將會(huì)出現(xiàn)下面的現(xiàn)象:

201638151308968.gif (320×120)201638151209028.gif (320×121)201638151327302.gif (319×127)

我們注意到都是FirstActivity的實(shí)例,但序列號(hào)不同,并且我們需要連續(xù)按后退鍵兩次,才能回到第一個(gè)FristActivity。standard模式的原理如下圖所示:

201638151352070.gif (440×212)

如圖所示,每次跳轉(zhuǎn)系統(tǒng)都會(huì)在task中生成一個(gè)新的FirstActivity實(shí)例,并且放于棧結(jié)構(gòu)的頂部,當(dāng)我們按下后退鍵時(shí),才能看到原來的FirstActivity實(shí)例。
這就是standard啟動(dòng)模式,不管有沒有已存在的實(shí)例,都生成新的實(shí)例。

2.singleTop
我們?cè)谏厦娴幕A(chǔ)上為<activity>指定屬性android:launchMode="singleTop",系統(tǒng)就會(huì)按照singleTop啟動(dòng)模式處理跳轉(zhuǎn)行為。我們重復(fù)上面幾個(gè)動(dòng)作,將會(huì)出現(xiàn)下面的現(xiàn)象:

201638151417517.gif (320×124)201638151838515.gif (320×124)201638151858469.gif (320×124)

我們看到這個(gè)結(jié)果跟standard有所不同,三個(gè)序列號(hào)是相同的,也就是說使用的都是同一個(gè)FirstActivity實(shí)例;如果按一下后退鍵,程序立即退出,說明當(dāng)前棧結(jié)構(gòu)中只有一個(gè)Activity實(shí)例。singleTop模式的原理如下圖所示:

201638151434213.gif (522×176)

正如上圖所示,跳轉(zhuǎn)時(shí)系統(tǒng)會(huì)先在棧結(jié)構(gòu)中尋找是否有一個(gè)FirstActivity實(shí)例正位于棧頂,如果有則不再生成新的,而是直接使用。也許朋友們會(huì)有疑問,我只看到棧內(nèi)只有一個(gè)Activity,如果是多個(gè)Activity怎么辦,如果不是在棧頂會(huì)如何?我們接下來再通過一個(gè)示例來證實(shí)一下大家的疑問。
我們?cè)傩陆ㄒ粋€(gè)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跳轉(zhuǎn)代碼改為:

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

 
是的,F(xiàn)irstActivity會(huì)跳轉(zhuǎn)到SecondActivity,SecondActivity又會(huì)跳轉(zhuǎn)到FirstActivity。演示結(jié)果如下:

201638151515857.gif (319×123)201638151530469.gif (320×118)201638151550299.gif (320×116)

我們看到,兩個(gè)FirstActivity的序列號(hào)是不同的,證明從SecondActivity跳轉(zhuǎn)到FirstActivity時(shí)生成了新的FirstActivity實(shí)例。原理圖如下:

201638151628506.gif (320×119)201638151647962.gif (320×120)201638151701357.gif (320×119)201638151723858.gif (320×120)

我們看到,當(dāng)從SecondActivity跳轉(zhuǎn)到FirstActivity時(shí),系統(tǒng)發(fā)現(xiàn)存在有FirstActivity實(shí)例,但不是位于棧頂,于是重新生成一個(gè)實(shí)例。
這就是singleTop啟動(dòng)模式,如果發(fā)現(xiàn)有對(duì)應(yīng)的Activity實(shí)例正位于棧頂,則重復(fù)利用,不再生成新的實(shí)例。

3.singleTask
在上面的基礎(chǔ)上我們修改FirstActivity的屬性android:launchMode="singleTask"。演示的結(jié)果如下:

我們注意到,在上面的過程中,F(xiàn)irstActivity的序列號(hào)是不變的,SecondActivity的序列號(hào)卻不是唯一的,說明從SecondActivity跳轉(zhuǎn)到FirstActivity時(shí),沒有生成新的實(shí)例,但是從FirstActivity跳轉(zhuǎn)到SecondActivity時(shí)生成了新的實(shí)例。singleTask模式的原理圖如下圖所示:

201638151803687.gif (440×400)

在圖中的下半部分是SecondActivity跳轉(zhuǎn)到FirstActivity后的棧結(jié)構(gòu)變化的結(jié)果,我們注意到,SecondActivity消失了,沒錯(cuò),在這個(gè)跳轉(zhuǎn)過程中系統(tǒng)發(fā)現(xiàn)有存在的FirstActivity實(shí)例,于是不再生成新的實(shí)例,而是將FirstActivity之上的Activity實(shí)例統(tǒng)統(tǒng)出棧,將FirstActivity變?yōu)闂m攲?duì)象,顯示到幕前。也許朋友們有疑問,如果將SecondActivity也設(shè)置為singleTask模式,那么SecondActivity實(shí)例是不是可以唯一呢?在我們這個(gè)示例中是不可能的,因?yàn)槊看螐腟econdActivity跳轉(zhuǎn)到FirstActivity時(shí),SecondActivity實(shí)例都被迫出棧,下次等FirstActivity跳轉(zhuǎn)到SecondActivity時(shí),找不到存在的SecondActivity實(shí)例,于是必須生成新的實(shí)例。但是如果我們有ThirdActivity,讓SecondActivity和ThirdActivity互相跳轉(zhuǎn),那么SecondActivity實(shí)例就可以保證唯一。
這就是singleTask模式,如果發(fā)現(xiàn)有對(duì)應(yīng)的Activity實(shí)例,則使此Activity實(shí)例之上的其他Activity實(shí)例統(tǒng)統(tǒng)出棧,使此Activity實(shí)例成為棧頂對(duì)象,顯示到幕前。

4.singleInstance
這種啟動(dòng)模式比較特殊,因?yàn)樗鼤?huì)啟用一個(gè)新的棧結(jié)構(gòu),將Acitvity放置于這個(gè)新的棧結(jié)構(gòu)中,并保證不再有其他Activity實(shí)例進(jìn)入。
我們修改FirstActivity的launchMode="standard",SecondActivity的launchMode="singleInstance",由于涉及到了多個(gè)棧結(jié)構(gòu),我們需要在每個(gè)Activity中顯示當(dāng)前棧結(jié)構(gòu)的id,所以我們?yōu)槊總€(gè)Activity添加如下代碼:

TextView taskIdView = (TextView) findViewById(R.id.taskIdView); 
taskIdView.setText("current task id: " + this.getTaskId()); 

然后我們?cè)傺菔疽幌逻@個(gè)流程:

201638151951749.gif (320×142)201638152011045.gif (319×139)

我們發(fā)現(xiàn)這兩個(gè)Activity實(shí)例分別被放置在不同的棧結(jié)構(gòu)中,關(guān)于singleInstance的原理圖如下:

201638152030493.gif (692×373)

我們看到從FirstActivity跳轉(zhuǎn)到SecondActivity時(shí),重新啟用了一個(gè)新的棧結(jié)構(gòu),來放置SecondActivity實(shí)例,然后按下后退鍵,再次回到原始棧結(jié)構(gòu);圖中下半部分顯示的在SecondActivity中再次跳轉(zhuǎn)到FirstActivity,這個(gè)時(shí)候系統(tǒng)會(huì)在原始棧結(jié)構(gòu)中生成一個(gè)FirstActivity實(shí)例,然后回退兩次,注意,并沒有退出,而是回到了SecondActivity,為什么呢?是因?yàn)閺腟econdActivity跳轉(zhuǎn)到FirstActivity的時(shí)候,我們的起點(diǎn)變成了SecondActivity實(shí)例所在的棧結(jié)構(gòu),這樣一來,我們需要“回歸”到這個(gè)棧結(jié)構(gòu)。
如果我們修改FirstActivity的launchMode值為singleTop、singleTask、singleInstance中的任意一個(gè),流程將會(huì)如圖所示:

201638152048827.gif (636×174)

singleInstance啟動(dòng)模式可能是最復(fù)雜的一種模式,為了幫助大家理解,我舉一個(gè)例子,假如我們有一個(gè)share應(yīng)用,其中的ShareActivity是入口Activity,也是可供其他應(yīng)用調(diào)用的Activity,我們把這個(gè)Activity的啟動(dòng)模式設(shè)置為singleInstance,然后在其他應(yīng)用中調(diào)用。我們編輯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> 

 
然后我們?cè)谄渌麘?yīng)用中這樣啟動(dòng)該Activity:

Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE"); 
startActivity(intent); 

當(dāng)我們打開ShareActivity后再按后退鍵回到原來界面時(shí),ShareActivity做為一個(gè)獨(dú)立的個(gè)體存在,如果這時(shí)我們打開share應(yīng)用,無需創(chuàng)建新的ShareActivity實(shí)例即可看到結(jié)果,因?yàn)橄到y(tǒng)會(huì)自動(dòng)查找,存在則直接利用。大家可以在ShareActivity中打印一下taskId,看看效果。關(guān)于這個(gè)過程,原理圖如下:

201638152118151.gif (576×155)

相關(guān)文章

最新評(píng)論