Android Activity的載入的模式

來源:互聯網
上載者:User

標籤:

---恢複內容開始---

本文來自http://www.cnblogs.com/lwbqqyumidi/p/3771542.html

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代碼如下:

 1 package com.scott.launchmode; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; 9 10 public class FirstActivity extends Activity {11     @Override12     public void onCreate(Bundle savedInstanceState) {13         super.onCreate(savedInstanceState);14         setContentView(R.layout.first);15         TextView textView = (TextView) findViewById(R.id.textView);16         textView.setText(this.toString());17         Button button = (Button) findViewById(R.id.button);18         button.setOnClickListener(new View.OnClickListener() {19             @Override20             public void onClick(View v) {21                 Intent intent = new Intent(FirstActivity.this, FirstActivity.class);22                 startActivity(intent);23             }24         });25     }26 }

我們FirstActivity介面中的TextView用於顯示當前Activity執行個體的序號,Button用於跳轉到下一個FirstActivity介面。

然後我們連續點擊幾次按鈕,將會出現下面的現象:

我們注意到都是FirstActivity的執行個體,但序號不同,並且我們需要連續按後退鍵兩次,才能回到第一個FristActivity。standard模式的原理如所示:

,每次跳轉系統都會在task中產生一個新的FirstActivity執行個體,並且放於棧結構的頂部,當我們按下後退鍵時,才能看到原來的FirstActivity執行個體。

這就是standard啟動模式,不管有沒有已存在的執行個體,都產生新的執行個體。

簡單點理解:standard啟動模式Activity棧從棧底到棧頂順序為A1 -> B -> C -> A2...。(其中A、B、C等都表示不同的Activity執行個體,A1、A2則表示屬於具有同一Activity類的不同執行個體)

 

2.singleTop

我們在上面的基礎上為<activity>指定屬性android:launchMode="singleTop",系統就會按照singleTop啟動模式處理跳轉行為。我們重複上面幾個動作,將會出現下面的現象:

我們看到這個結果跟standard有所不同,三個序號是相同的,也就是說使用的都是同一個FirstActivity執行個體;如果按一下後退鍵,程式立即退出,說明當前棧結構中只有一個Activity執行個體。singleTop模式的原理如所示:

正如所示,跳轉時系統會先在棧結構中尋找是否有一個FirstActivity執行個體正位於棧頂,如果有則不再產生新的,而是直接使用。也許朋友們會有疑問,我只看到棧內只有一個Activity,如果是多個Activity怎麼辦,如果不是在棧頂會如何?我們接下來再通過一個樣本來證實一下大家的疑問。

我們再建立一個Activity命名為SecondActivity,如下:

 1 package com.scott.launchmode; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; 9 10 public class SecondActivity extends Activity {11     @Override12     protected void onCreate(Bundle savedInstanceState) {13         super.onCreate(savedInstanceState);14         setContentView(R.layout.second);15         TextView textView = (TextView) findViewById(R.id.textView);16         textView.setText(this.toString());17         Button button = (Button) findViewById(R.id.button);18         button.setOnClickListener(new View.OnClickListener() {19             @Override20             public void onClick(View v) {21                 Intent intent = new Intent(SecondActivity.this, FirstActivity.class);22                 startActivity(intent);                23             }24         });25     }26 }

然後將之前的FirstActivity跳轉代碼改為:

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

是的,FirstActivity會跳轉到SecondActivity,SecondActivity又會跳轉到FirstActivity。示範結果如下:

 

我們看到,兩個FirstActivity的序號是不同的,證明從SecondActivity跳轉到FirstActivity時產生了新的FirstActivity執行個體。原理圖如下:

我們看到,當從SecondActivity跳轉到FirstActivity時,系統發現存在有FirstActivity執行個體,但不是位於棧頂,於是重建一個執行個體。

這就是singleTop啟動模式,如果發現有對應的Activity執行個體正位於棧頂,則重複利用,不再產生新的執行個體。

簡單點理解,singleTop即表示當前Activity棧中“棧頂唯一”,Activity跳轉順序或standard模式下棧結構如果為:A -> B -> C -> D1 -> D2,則singleTop啟動模式為:A -> B -> C -> D1(此時回調D1的onNewIntent()..)

 

3.singleTask

在上面的基礎上我們修改FirstActivity的屬性android:launchMode="singleTask"。示範的結果如下:

我們注意到,在上面的過程中,FirstActivity的序號是不變的,SecondActivity的序號卻不是唯一的,說明從SecondActivity跳轉到FirstActivity時,沒有產生新的執行個體,但是從FirstActivity跳轉到SecondActivity時產生了新的執行個體。singleTask模式的原理圖如所示:

在圖中的下半部分是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執行個體統統出棧,使此Activity執行個體成為棧頂對象,顯示到幕前。

簡單點理解,singleTask表示當前Activity棧中“執行個體唯一”,Activity跳轉順序或standard模式下棧結構如果為:A -> B1 -> C -> D -> B2,則singleTask啟動模式為:A -> B1(此時回調onNewIntent()..)

 

4.singleInstance

這種啟動模式比較特殊,因為它會啟用一個新的棧結構,將Acitvity放置於這個新的棧結構中,並保證不再有其他Activity執行個體進入。

我們修改FirstActivity的launchMode="standard",SecondActivity的launchMode="singleInstance",由於涉及到了多個棧結構,我們需要在每個Activity中顯示當前棧結構的id,所以我們為每個Activity添加如下代碼:

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

然後我們再示範一下這個流程:

 

我們發現這兩個Activity執行個體分別被放置在不同的棧結構中,關於singleInstance的原理圖如下:

我們看到從FirstActivity跳轉到SecondActivity時,重新啟用了一個新的棧結構,來放置SecondActivity執行個體,然後按下後退鍵,再次回到原始棧結構;圖中下半部分顯示的在SecondActivity中再次跳轉到FirstActivity,這個時候系統會在原始棧結構中產生一個FirstActivity執行個體,然後回退兩次,注意,並沒有退出,而是回到了SecondActivity,為什麼呢?是因為從SecondActivity跳轉到FirstActivity的時候,我們的起點變成了SecondActivity執行個體所在的棧結構,這樣一來,我們需要“迴歸”到這個棧結構。

此處的解釋不是很贊同,第一次按Back鍵首先是在當前Activity棧中將棧頂元素出棧,然後顯示當前Activity棧中下一個Activity棧,這個沒什麼解釋的,然後按下Back鍵,不是回到手機案頭,而是回到另一個Activity棧中的SecondActivityInstance,我認為原因在於在於“最近棧”,只要此棧位於上次Home操作之後,就會先顯示它。

如果我們修改FirstActivity的launchMode值為singleTop、singleTask、singleInstance中的任意一個,流程將會:

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:

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

當我們開啟ShareActivity後再按後退鍵回到原來介面時,ShareActivity做為一個獨立的個體存在,如果這時我們開啟share應用,無需建立新的ShareActivity執行個體即可看到結果,因為系統會自動尋找,存在則直接利用。大家可以在ShareActivity中列印一下taskId,看看效果。關於這個過程,原理圖如下:

 

原作者此處的解釋可能有點讓人誤解。當我們開啟ShareActivity後再按後退鍵回到原來介面時,ShareActivity做為一個獨立的個體存在,此處不應該是按Back鍵,而是Home鍵,因為一旦按下了Back鍵,ShrareActivityInstance自然就銷毀了,也就不存在所謂的“無須重新建立了”。按下Home鍵後,接下來開啟app MainActivity,在另一個Activity棧中app MainActivity入棧,此時startActivity到ShareActivity,無需建立新的ShareActivity執行個體即可看到結果,因為系統會自動尋找,存在則直接利用。此時第一次按下Back,ShareActivity Instance出棧,此時這個棧中沒有其他Activity了,自然是回到了app MainActivity所在的棧並顯示app MainActivity,接下來按Back鍵,此時app MainActivity所在的棧也沒有其他Activity了,同時又不包含任何其他的“最近棧”,自然是回到了手機案頭。註:此處理解的“最近棧”是以Home鍵或案頭狀態為間隔區分。

簡單點理解,singleInstance所標識的Activity,當被啟動時,系統會首先判斷系統其他棧中是否已經存在此Activity執行個體,有則直接使用,並且其所在的Activity棧理論上只有它一個Activity元素。所以啟動它的Activity與它並不在一個task中,所以才需要特別注意Back的問題。一般表示為:task1 A -> task2 B。

singleInstance表示該Activity在系統範圍內“執行個體唯一”。由此我們發現,singInstance和singleTask主要區別在與系統範圍內的“執行個體唯一”還是當前Activity棧“執行個體唯一”。

---恢複內容結束---

本文來自http://www.cnblogs.com/lwbqqyumidi/p/3771542.html

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代碼如下:

 1 package com.scott.launchmode; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; 9 10 public class FirstActivity extends Activity {11     @Override12     public void onCreate(Bundle savedInstanceState) {13         super.onCreate(savedInstanceState);14         setContentView(R.layout.first);15         TextView textView = (TextView) findViewById(R.id.textView);16         textView.setText(this.toString());17         Button button = (Button) findViewById(R.id.button);18         button.setOnClickListener(new View.OnClickListener() {19             @Override20             public void onClick(View v) {21                 Intent intent = new Intent(FirstActivity.this, FirstActivity.class);22                 startActivity(intent);23             }24         });25     }26 }

我們FirstActivity介面中的TextView用於顯示當前Activity執行個體的序號,Button用於跳轉到下一個FirstActivity介面。

然後我們連續點擊幾次按鈕,將會出現下面的現象:

我們注意到都是FirstActivity的執行個體,但序號不同,並且我們需要連續按後退鍵兩次,才能回到第一個FristActivity。standard模式的原理如所示:

,每次跳轉系統都會在task中產生一個新的FirstActivity執行個體,並且放於棧結構的頂部,當我們按下後退鍵時,才能看到原來的FirstActivity執行個體。

這就是standard啟動模式,不管有沒有已存在的執行個體,都產生新的執行個體。

簡單點理解:standard啟動模式Activity棧從棧底到棧頂順序為A1 -> B -> C -> A2...。(其中A、B、C等都表示不同的Activity執行個體,A1、A2則表示屬於具有同一Activity類的不同執行個體)

 

2.singleTop

我們在上面的基礎上為<activity>指定屬性android:launchMode="singleTop",系統就會按照singleTop啟動模式處理跳轉行為。我們重複上面幾個動作,將會出現下面的現象:

我們看到這個結果跟standard有所不同,三個序號是相同的,也就是說使用的都是同一個FirstActivity執行個體;如果按一下後退鍵,程式立即退出,說明當前棧結構中只有一個Activity執行個體。singleTop模式的原理如所示:

正如所示,跳轉時系統會先在棧結構中尋找是否有一個FirstActivity執行個體正位於棧頂,如果有則不再產生新的,而是直接使用。也許朋友們會有疑問,我只看到棧內只有一個Activity,如果是多個Activity怎麼辦,如果不是在棧頂會如何?我們接下來再通過一個樣本來證實一下大家的疑問。

我們再建立一個Activity命名為SecondActivity,如下:

 1 package com.scott.launchmode; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; 9 10 public class SecondActivity extends Activity {11     @Override12     protected void onCreate(Bundle savedInstanceState) {13         super.onCreate(savedInstanceState);14         setContentView(R.layout.second);15         TextView textView = (TextView) findViewById(R.id.textView);16         textView.setText(this.toString());17         Button button = (Button) findViewById(R.id.button);18         button.setOnClickListener(new View.OnClickListener() {19             @Override20             public void onClick(View v) {21                 Intent intent = new Intent(SecondActivity.this, FirstActivity.class);22                 startActivity(intent);                23             }24         });25     }26 }

然後將之前的FirstActivity跳轉代碼改為:

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

是的,FirstActivity會跳轉到SecondActivity,SecondActivity又會跳轉到FirstActivity。示範結果如下:

 

我們看到,兩個FirstActivity的序號是不同的,證明從SecondActivity跳轉到FirstActivity時產生了新的FirstActivity執行個體。原理圖如下:

我們看到,當從SecondActivity跳轉到FirstActivity時,系統發現存在有FirstActivity執行個體,但不是位於棧頂,於是重建一個執行個體。

這就是singleTop啟動模式,如果發現有對應的Activity執行個體正位於棧頂,則重複利用,不再產生新的執行個體。

簡單點理解,singleTop即表示當前Activity棧中“棧頂唯一”,Activity跳轉順序或standard模式下棧結構如果為:A -> B -> C -> D1 -> D2,則singleTop啟動模式為:A -> B -> C -> D1(此時回調D1的onNewIntent()..)

 

3.singleTask

在上面的基礎上我們修改FirstActivity的屬性android:launchMode="singleTask"。示範的結果如下:

我們注意到,在上面的過程中,FirstActivity的序號是不變的,SecondActivity的序號卻不是唯一的,說明從SecondActivity跳轉到FirstActivity時,沒有產生新的執行個體,但是從FirstActivity跳轉到SecondActivity時產生了新的執行個體。singleTask模式的原理圖如所示:

在圖中的下半部分是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執行個體統統出棧,使此Activity執行個體成為棧頂對象,顯示到幕前。

簡單點理解,singleTask表示當前Activity棧中“執行個體唯一”,Activity跳轉順序或standard模式下棧結構如果為:A -> B1 -> C -> D -> B2,則singleTask啟動模式為:A -> B1(此時回調onNewIntent()..)

 

4.singleInstance

這種啟動模式比較特殊,因為它會啟用一個新的棧結構,將Acitvity放置於這個新的棧結構中,並保證不再有其他Activity執行個體進入。

我們修改FirstActivity的launchMode="standard",SecondActivity的launchMode="singleInstance",由於涉及到了多個棧結構,我們需要在每個Activity中顯示當前棧結構的id,所以我們為每個Activity添加如下代碼:

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

然後我們再示範一下這個流程:

 

我們發現這兩個Activity執行個體分別被放置在不同的棧結構中,關於singleInstance的原理圖如下:

我們看到從FirstActivity跳轉到SecondActivity時,重新啟用了一個新的棧結構,來放置SecondActivity執行個體,然後按下後退鍵,再次回到原始棧結構;圖中下半部分顯示的在SecondActivity中再次跳轉到FirstActivity,這個時候系統會在原始棧結構中產生一個FirstActivity執行個體,然後回退兩次,注意,並沒有退出,而是回到了SecondActivity,為什麼呢?是因為從SecondActivity跳轉到FirstActivity的時候,我們的起點變成了SecondActivity執行個體所在的棧結構,這樣一來,我們需要“迴歸”到這個棧結構。

此處的解釋不是很贊同,第一次按Back鍵首先是在當前Activity棧中將棧頂元素出棧,然後顯示當前Activity棧中下一個Activity棧,這個沒什麼解釋的,然後按下Back鍵,不是回到手機案頭,而是回到另一個Activity棧中的SecondActivityInstance,我認為原因在於在於“最近棧”,只要此棧位於上次Home操作之後,就會先顯示它。

如果我們修改FirstActivity的launchMode值為singleTop、singleTask、singleInstance中的任意一個,流程將會:

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:

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

當我們開啟ShareActivity後再按後退鍵回到原來介面時,ShareActivity做為一個獨立的個體存在,如果這時我們開啟share應用,無需建立新的ShareActivity執行個體即可看到結果,因為系統會自動尋找,存在則直接利用。大家可以在ShareActivity中列印一下taskId,看看效果。關於這個過程,原理圖如下:

 

原作者此處的解釋可能有點讓人誤解。當我們開啟ShareActivity後再按後退鍵回到原來介面時,ShareActivity做為一個獨立的個體存在,此處不應該是按Back鍵,而是Home鍵,因為一旦按下了Back鍵,ShrareActivityInstance自然就銷毀了,也就不存在所謂的“無須重新建立了”。按下Home鍵後,接下來開啟app MainActivity,在另一個Activity棧中app MainActivity入棧,此時startActivity到ShareActivity,無需建立新的ShareActivity執行個體即可看到結果,因為系統會自動尋找,存在則直接利用。此時第一次按下Back,ShareActivity Instance出棧,此時這個棧中沒有其他Activity了,自然是回到了app MainActivity所在的棧並顯示app MainActivity,接下來按Back鍵,此時app MainActivity所在的棧也沒有其他Activity了,同時又不包含任何其他的“最近棧”,自然是回到了手機案頭。註:此處理解的“最近棧”是以Home鍵或案頭狀態為間隔區分。

簡單點理解,singleInstance所標識的Activity,當被啟動時,系統會首先判斷系統其他棧中是否已經存在此Activity執行個體,有則直接使用,並且其所在的Activity棧理論上只有它一個Activity元素。所以啟動它的Activity與它並不在一個task中,所以才需要特別注意Back的問題。一般表示為:task1 A -> task2 B。

singleInstance表示該Activity在系統範圍內“執行個體唯一”。由此我們發現,singInstance和singleTask主要區別在與系統範圍內的“執行個體唯一”還是當前Activity棧“執行個體唯一”。

Android Activity的載入的模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.