標籤:
在Android系統中,一個application的所有Activity預設有一個相同的affinity(親密關係,相似之處)。也就是說同一個應用程式的的所有Activity傾向於屬於同一個task。但是我們並不能說Android裡一個應用程式只有一個任務棧。筆者今天針對當taskAffinity不同時,四種launchMode下在開啟一個新的Activity時是否會建立一個新的任務棧做了實驗。
基本的代碼如下:
AndroidManifest.xml:
MainActivity的代碼
package com.example.testlaunchmode;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.TextView;public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.tv); tv.setText(this.toString()+"\ntaskId="+this.getTaskId()); } public void onJump(View view) { Intent intent = new Intent(this, ActivityTest.class); startActivity(intent); } @Override protected void onNewIntent(Intent intent) { Log.d(TAG, "onNewIntent: intent="+intent); } }
ActivityTest的代碼和MainActivity類似,我就不貼出來了。
1. standard模式:
standard模式是預設模式。在該模式下,Activity可以擁有多個執行個體,並且這些執行個體既可以位於同一個task,也可以位於不同的task。
代碼如上面所示,沒有改動,運行結果如下:
點擊button後
可以看出,MainActivity和ActivityTest的taskAffinity並不相同,但是它們被放入同一個任務棧中。
2. singleTop模式
singleTop模式下,在同一個task中,如果存在該Activity的執行個體,並且該Activity執行個體位於棧頂(即,該Activity位於前端),則調用startActivity()時,不再建立該Activity的樣本;而僅僅只是調用Activity的onNewIntent()。否則的話,則建立該Activity的執行個體,並將其置於棧頂。
僅僅改動AndroidManifest.xml檔案:
運行結果:
點擊button後:
可以看出和standard模式一樣,雖然MainActivity和ActivityTest的taskAffinity不相同,但是它們仍然被放入同一個任務棧中。
3.singleTask模式:
這個模式筆者想先貼代碼和結果:
運行結果:
由上面的結果可以很明顯的看到ActivityTest開啟時被放到了一個新的任務棧中,成為新的任務棧的棧底元素,也就是文檔中所說的root activity。這時最新的任務棧成為唯一前台任務棧,而原來的MainActivity所在的任務棧成為眾多背景工作棧中的一個。
實驗做到這裡筆者產生了一個新的疑問:如果兩個Activity的taskAffinity相同,還會被這樣嗎?
因此筆者把兩個Activity的taskAffinity改成一樣的再次運行:
結果:
顯然這樣的結果和文檔中給出的-A "singleTask" activity will always be the root activity of the task-是不相符的。後來筆者在文檔中找到這樣一段話(設定了The FLAG_ACTIVITY_NEW_TASK flag):As described earlier, a new activity is, by default, launched into the task of the activity that called startActivity(). It‘s pushed onto the same stack as the caller. However, if the Intent object passed to startActivity() contains the FLAG_ACTIVITY_NEW_TASK flag, the system looks for a different task to house the new activity. Often, as the name of the flag implies, it‘s a new task. However, it doesn‘t have to be. If there‘s already an existing task with the same affinity as the new activity, the activity is launched into that task. If not, it begins a new task.
文檔這是紅果果的自相矛盾啊~QUQ
好扒,總結一下是這樣的:
以A啟動B來說
(01) 當A和B的taskAffinity相同時:第一次建立B的執行個體時,並不會啟動新的task,而是直接將B添加到A所在的task;當B的執行個體已經存在時,將B所在task中位於B之上的全部Activity都刪除,B就成為棧頂元素,實現跳轉到B的功能。
(02) 當A和B的taskAffinity不同時:第一次建立B的執行個體時,會啟動新的task,然後將B添加到建立的task中;當B的執行個體引進存在,將B所在task中位於B之上的全部Activity都刪除,B就成為棧頂元素(也是root Activity),實現跳轉到B的功能。
5. singleInstance模式
singleInstance,顧名思義,是單一執行個體的意思,即任意時刻只允許存在唯一的Activity執行個體!
根據文檔,在該模式下,只允許有一個該Activity的執行個體。當第一次建立該Activity執行個體時,會建立一個task,並將該Activity添加到該task中。注意:該task只能容納該Activity執行個體,不會再添加其他的Activity執行個體!如果該Activity執行個體已經存在於某個task,則直接跳轉到該task。
顯然這和文檔的描述是相符的~
注意:standard和singleTop模式下被啟動的Activity的執行個體都可能不只一個,但是singleTask和和singleInstance都是只有一個執行個體存在的。區別是:
1.A "singleInstance" activity is always at the top of the stack (since it is the only activity in the task).(既是棧頂又是棧底)
2.However, a "singleTask" activity may or may not have other activities above it in the stack。(上面還可能有其它的Activity,也不一定是root Activity)
Android的taskAffinity對四種launchMode的影響