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的例項,但序列號不同,並且我們需要連續按後退鍵兩次,才能回到第一個FristActivity。standard模式的原理如下圖所示:
如圖所示,每次跳轉系統都會在task中生成一個新的FirstActivity例項,並且放於棧結構的頂部,當我們按下後退鍵時,才能看到原來的FirstActivity例項。
這就是standard啟動模式,不管有沒有已存在的例項,都生成新的例項。
2.singleTop
我們在上面的基礎上為<activity>指定屬性android:launchMode="singleTop",系統就會按照singleTop啟動模式處理跳轉行為。我們重複上面幾個動作,將會出現下面的現象:
我們看到這個結果跟standard有所不同,三個序列號是相同的,也就是說使用的都是同一個FirstActivity例項;如果按一下後退鍵,程式立即退出,說明當前棧結構中只有一個Activity例項。singleTop模式的原理如下圖所示:
正如上圖所示,跳轉時系統會先在棧結構中尋找是否有一個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);
- }
- });
- }
- }
- Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
- startActivity(intent);
我們看到,兩個FirstActivity的序列號是不同的,證明從SecondActivity跳轉到FirstActivity時生成了新的FirstActivity例項。原理圖如下:
我們看到,當從SecondActivity跳轉到FirstActivity時,系統發現存在有FirstActivity例項,但不是位於棧頂,於是重新生成一個例項。
這就是singleTop啟動模式,如果發現有對應的Activity例項正位於棧頂,則重複利用,不再生成新的例項。
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例項成為棧頂物件,顯示到幕前。
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());
我們發現這兩個Activity例項分別被放置在不同的棧結構中,關於singleInstance的原理圖如下:
我們看到從FirstActivity跳轉到SecondActivity時,重新啟用了一個新的棧結構,來放置SecondActivity例項,然後按下後退鍵,再次回到原始棧結構;圖中下半部分顯示的在SecondActivity中再次跳轉到FirstActivity,這個時候系統會在原始棧結構中生成一個FirstActivity例項,然後回退兩次,注意,並沒有退出,而是回到了SecondActivity,為什麼呢?是因為從SecondActivity跳轉到FirstActivity的時候,我們的起點變成了SecondActivity例項所在的棧結構,這樣一來,我們需要“迴歸”到這個棧結構。
如果我們修改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>
- Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE");
- startActivity(intent);
相關文章
- Android中的Activity四種啟動模式(launchMode)Android模式
- Activity 的 Task 以及 launchMode 研究
- 喜聞樂見之Activity的launchMode
- activity四種啟動模式模式
- android-Activity Intent.setFlags()與launchModeAndroidIntent
- Android中Activity的啟動模式(LaunchMode)和使用場景Android模式
- Android的activity的四種啟動方式Android
- Android中Activity的四種啟動方式Android
- android Task Activity launchMode="singleTask" singleInstance 程式碼分析Android
- Android四大元件——Activity——Activity的生命週期Android元件
- 四大元件之Activity元件
- Android LaunchMode使用場景Android
- Activity與Service通訊的方式有三種:
- Android 四大元件之 ActivityAndroid元件
- Android四大元件之ActivityAndroid元件
- 四大元件之Activity_Fragment元件Fragment
- Android 四大元件之 " Activity "Android元件
- Android的Activity共享變數的另一種做法Android變數
- 檢視Androi的appPackage和Activity的多種方法APPPackage
- 安卓開發之Activity的4種啟動模式安卓模式
- Activity和Service跨程式通訊的兩種方式
- Android Activity的四大啟動模式詳解Android模式
- Java的四種引用Java
- Android中Activity執行restart過程中涉及到的四種資料儲存恢復的方法AndroidREST
- Android 8.0 原始碼分析 (四) Activity 啟動Android原始碼
- Android四大元件之Activity篇Android元件
- OAuth 2.0 的四種方式OAuth
- CSS的四種引入方式CSS
- 啟動另外的一個應用程式的Activity(三種方式)
- Android必知必會的四大元件 -- Activity篇Android元件
- 重溫Android四大元件—Activity的生命週期Android元件
- 【Android】安卓四大元件之Activity(二)Android安卓元件
- 學習筆記 AS入門(四) 元件篇之Activity筆記元件
- Android面試常客--四大元件之ActivityAndroid面試元件
- java中Stream的四種建立Java
- Java 四種引用的解讀Java
- Spark的四種部署方式概括Spark
- PostgreSQL的四種程式間鎖SQL