Android初級開發筆記-- Activity啓動模式的學習(2)

在上篇文章中已經介紹了和啓動模式相關的基礎知識,想了解的小夥伴能夠戳下方連接:blog.csdn.net/qq_42171948…android

在對activity四種啓動模式有所理解以後。這篇文章將會繼續解決上篇所留下的問題瀏覽器

1.如何設置不一樣的任務棧?bash

2.當activityA以標準模式啓動B的時候,B的實例被建立且處於activityA任務棧的頂端,那麼這個時候B啓動了A(standard)呢?app

3.這兩種設置方式有什麼區別呢?經常使用的標誌位有好幾個,組合起來使用又有什麼不一樣的效果呢?ide

咱們知道,默認狀況下,全部activity都運行在同一個任務棧中,此棧名爲 元素設置的軟件包名稱。那麼如何設置不一樣的任務棧,很簡單,用taskAffinity。學習

taskAffinity

taskAffinity是一個代表activity想在哪一個任務棧的參數。在manifest裏面能夠進行設置。ui

<activity android:name=".MainActivity"
            android:taskAffinity="com.example.administrator.test">
複製代碼
  • 每一個Activity都有taskAffinity屬性,這個屬性指出了它但願進入的Task。默認是包名。
  • 每一個task有affinity屬性,等於它的根 Activity的taskAffinity的值。
  • 在不設置其餘的前提下,經檢驗,只有在singleTask,和singleInstance模式中,taskAffinity纔會起到應有的做用。 貼上代碼: 當兩個activity的taskAffinity不同時: manifest:
<activity android:name=".MainActivity"
            android:taskAffinity="com.example.administrator.test">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity2"
            android:launchMode="singleTask"
            android:taskAffinity="com.example.administrator.test1">
        </activity>
複製代碼

mainactivity:this

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView show = (TextView) findViewById(R.id.tv_show);

        show.setText(this.toString() + "\ntaskId:" + this.getTaskId());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("task", "intent1=" + intent);
    }

    public void jump(View v) {
        Intent intent = new Intent(this,MainActivity2.class);
        startActivity(intent);
    }
}
複製代碼

mainactivity2:spa

public class MainActivity2 extends AppCompatActivity{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        TextView show = (TextView) findViewById(R.id.tv_show);

        show.setText(this.toString() + "\ntaskId:" + this.getTaskId());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("task","intent2"+intent);
    }
}
複製代碼

現象是: .net

1.png
2.png

當兩個activity的taskAffinity同樣時:

3.png
4.png

由此能夠得出結論: 以1啓動2來講

  • (1) 當1和2的taskAffinity相同時:當第一次建立2 的實例時,並不會建立新的task,乃是將在1的task中建立2的實例;當1的task已經存在2的實例時,此時啓動2,則會檢查一下task中是否有2實例,而後將2上的其餘實例出棧,將2實例置於棧頂,從而實現了跳轉。

  • (2) 當1和2的taskAffinity不一樣時:當第一次建立2 的實例時,將會建立新的task,在指定的task中建立2的實例;當指定task已經存在2的實例時,此時啓動2,則會檢查一下task中是否有2實例,而後將2上的其餘實例出棧,將2實例置於棧頂,從而實現了跳轉。

  • 說了這麼多,其實就是很簡單的一句話,taskAffinity設置新啓動的activity應處於哪一個task,一種是在建立它的activity所處棧,一種是新棧,其餘的分析就是對singleTask的理解而已。

另外,文檔給咱們提供了一種會出現:原本在某一個Task中,以後出現了轉移的狀況。 若是該Activity的allowTaskReparenting屬性設置爲true,當啓動它的任務棧進入後臺,一個和它有相同affinity的Task進入前臺時,該Activity會進入到該前臺的task中。

(如下是翻譯) 例子是,若是電子郵件包含網頁連接,則點擊連接會調出可顯示網頁的 Activity。 該 Activity 由瀏覽器應用定義,但做爲電子郵件任務的一部分啓動。 若是將其父項更改成瀏覽器任務,它會在瀏覽器下一次轉至前臺時顯示,當電子郵件任務再次轉至前臺時則會消失。

個人理解:當一個應用A啓動了應用B的某個ActivityC後(C的taskAffinity 爲B),若是咱們將ActivityC的allowTaskReparenting屬性設置爲true,當應用B被啓動後,系統會發現Activity C所需的任務棧已經存在,ActivityC就會從A的任務棧轉移到B的任務棧中。

(如下仍是翻譯) Activity 的親和關係由 taskAffinity 屬性定義。 任務的親和關係經過讀取其根 Activity 的親和關係來肯定。所以,按照定義,根 Activity 始終位於具備相同親和關係的任務之中。 因爲具備「singleTask」或「singleInstance」啓動模式的 Activity 只能位於任務的根,所以更改父項僅限於「standard」和「singleTop」模式。

個人理解: 每一個task有affinity屬性,等於它的根 Activity的taskAffinity的值。singletask和singleinstance模式下,Atask中只能有一個A實例,且爲根,那麼就不能從新宿主,要否則的話這個棧就崩了呢~而另外兩種的話,由於不是根因此能夠在特定情境下自由遊蕩。(若理解得不對,望小夥伴指正)

寫在最後

因爲篇幅和時間關係,文章就到此結束,剩下的問題待Android初級開發筆記-- Activity啓動模式的學習(3)再進行討論~

內推信息

  • 咱們正在招募小夥伴,有興趣的小夥伴能夠把簡歷發到 app@talkmoney.cn,備註:來自簡書社區
  • 詳情能夠戳這裏--> 廣州蘆葦信息科技
相關文章
相關標籤/搜索