Android中Activity的LunchMode引數詳解

yangxi_001發表於2013-11-21

在Android中,每個Activity有4種LaunchMode,分別是:standard、singleTop、singleTask、singleInstance,預設是standard。在AndroidManifest.xml的對應Activity中配置該引數。下面對這四種模式進行例項驗證加深理解。

        設計兩個Activity,分別稱為A,B,每個Activity上面都放置兩個按鈕,一個啟動A,一個啟動B。介面如下:(上面的一行文字用來識別是在A介面還是在B介面)

此圖為A介面,B介面沒有最上一行的字。

 

A介面java程式碼如下:

[java] view plaincopy
  1. public class LunchModeActivityA extends Activity {  
  2.     @Override  
  3.     public void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6.           
  7.         Button buttonActivityA = (Button) this.findViewById(R.id.buttonActivityA);  
  8.         Button buttonActivityB = (Button) this.findViewById(R.id.buttonActivityB);  
  9.         //啟動ActivityB  
  10.         buttonActivityA.setOnClickListener(new OnClickListener() {  
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 Intent _intentB = new Intent(LunchModeActivityA.this,LunchModeActivityB.class);  
  14.                 startActivity(_intentB);  
  15.             }  
  16.         });  
  17.           
  18.         //啟動ActivityA  
  19.         buttonActivityB.setOnClickListener(new OnClickListener() {  
  20.             @Override  
  21.             public void onClick(View v) {  
  22.                 Intent _intentA = new Intent(LunchModeActivityA.this,LunchModeActivityA.class);  
  23.                 startActivity(_intentA);  
  24.             }  
  25.         });  
  26.         Log.i("LunchModeActivityA","Task:"+getTaskId()+" LunchModeActivityA onCreate.");  
  27.     }  
  28.   
  29.     @Override  
  30.     protected void onDestroy() {  
  31.         super.onDestroy();  
  32.         Log.i("LunchModeActivityA","Task:"+getTaskId()+" LunchModeActivityA onDestroy.");  
  33.     }  
  34.       
  35.     @Override  
  36.     protected void onNewIntent(Intent intent) {  
  37.         super.onNewIntent(intent);  
  38.         Log.i("LunchModeActivityA","Task:"+getTaskId()+" LunchModeActivityA onNewIntent.");  
  39.     }  
  40. }  


同理,LunchModeActivityB也類似實現,重灌上面三個方法並進行log跟蹤。

 

測試開始:

1.兩個Actiity的LaunchMode都為預設的standard,啟動Ap,看到輸出:
Task:11 LunchModeActivityA onCreate.

A被建立了一個例項A,並且放在了任務11中。 
此時任務棧中內容為: 


點選介面上啟動A的按鈕,看到輸出: 
Task:11 LunchModeActivityA onCreate.

A再次被建立了一個新的例項A,仍然放在任務11中。 
此時任務棧中內容為: 
AA 

點選啟動B的按鈕, 
Task:11 LunchModeActivityB onCreate. 

B被建立一個新的例項B,仍然放在任務11中。 
此時任務棧內容為: 
AAB 

再啟動B, 
Task:11 LunchModeActivityB onCreate. 

B又被建立了一個新的例項B,仍然在任務11中。 
任務棧內容為: 
AABB 

按Back鍵依次返回桌面,輸出依次為: 
Task:11 LunchModeActivityB onDestroy.

Task:11 LunchModeActivityB onDestroy.

Task:11 LunchModeActivityA onDestroy.

Task:11 LunchModeActivityA onDestroy. 

任務棧的變化次序為: 
AABB 
AAB 
AA 


結論: 
每個Intent,都建立了一個新的Activity來響應,並且Back時是按照彈棧的順序處理的。

2.B設定為SingleTop,啟動Ap:
 
Task:12 LunchModeActivityA onCreate.

再啟動A: 
Task:12 LunchModeActivityA onCreate.

再啟動B: 
Task:12 LunchModeActivityB onCreate. 

再啟動B: 
Task:12 LunchModeActivityB onNewIntent.

結論: 
當B不在棧頂時,仍然會建立B的新例項。 
當B在棧頂時,請求啟動B的Intent並沒有觸發建立B的新例項,而是觸發了棧頂B的onNewIntent()
 

按Back鍵依次返回桌面,輸出依次為: 
Task:12 LunchModeActivityB onDestroy.

Task:12 LunchModeActivityA onDestroy.

Task:12 LunchModeActivityA onDestroy.

結論: 
雖然傳送了四次Intent,但實際上只建立了3個Activity,所以只有3次銷燬輸出。
 

3.B設定為SingleTask,啟動Ap:
 
Task:3 LunchModeActivityA onCreate.

啟動B: 
Task:3 LunchModeActivityB onCreate.

啟動A: 
Task:3 LunchModeActivityA onCreate. 

啟動B: 
Task:3 LunchModeActivityB onNewIntent. 
Task:3 LunchModeActivityA destroyed. 

結論: 
當B已經存在時,再次請求B會觸發已經存在的B例項的onNewIntent; 
並且如果B所在的任務棧上面有其他Activity,那麼其他Activity會被銷燬。
 

4.B設定為SingleInstance,啟動Ap:
 
Task:4 LunchModeActivityA onCreate.

啟動B,此時新建立了任務棧5,和先前的A並不在一個任務。 
Task:5 LunchModeActivityB onCreate.

再啟動B,沒有建立新例項: 
Task:5 LunchModeActivityB onNewIntent.


再啟動A,再舊的任務4中建立了A的新例項 
Task:4 LunchModeActivityA onCreate.

按下Back鍵: 
Task:4 LunchModeActivityA onDestroy.

看輸出和前面沒區別,但是注意介面,此時不是切換到B介面,因為此時活動任務是4,所以A被顯示了出來


再次按下Back鍵: 
Task:4 LunchModeActivityA onDestroy.

此時因為任務4已經結束,B所在的任務5成為活動任務,B的介面才被顯示出來。

 

總結:被該屬性表示的Activity會標記成另一個Taskid,並且該Activity的例項不會重複建立,back的時候是最後一個顯示和退出的。

相關文章