Android TaskAffinity實踐詳解

介紹

其實一直以來都知道在AndroidManifest的Activity中能夠配置TaskAffinity這個屬性,只知道這個東西和Activity的任務棧有關,今天花了點時間好好學習了一些這個東西。javascript

launchMode(啓動模式)

Activity的任務棧是咱們很熟悉的了,它是一種後進先出的結構。位於棧頂的Activity處於焦點狀態,當按下back按鈕的時候,棧內的Activity會一個一個的出棧,而且調用其onDestory()方法。若是棧內沒有Activity,那麼系統就會回收這個棧,每一個APP默認只有一個棧,以APP的包名來命名.java

1.
standard: 標準模式,每次啓動Activity都會建立一個新的Activity實例,而且將其壓入任務棧棧頂,而無論這個Activity是否已經存在。Activity的啓動三回調(onCreate()->onStart()->onResume())都會執行。學習

2.
singleTop: 棧頂複用模式.這種模式下,若是新Activity已經位於任務棧的棧頂,那麼此Activity不會被從新建立,因此它的啓動三回調就不會執行,同時Activity的onNewIntent()方法會被回調.若是Activity已經存在可是不在棧頂,那麼做用與standard模式同樣.spa

3.
singleTask: 棧內複用模式.建立這樣的Activity的時候,系統會先確認它所需任務棧已經建立,不然先建立任務棧.而後放入Activity,若是棧中已經有一個Activity實例,那麼這個Activity就會被調到棧頂,onNewIntent(),而且singleTask會清理在當前Activity上面的全部Activity.(clear top)3d

4.
singleInstance: 增強版的singleTask模式,這種模式的Activity只能單獨位於一個任務棧內,因爲棧內複用的特性,後續請求均不會建立新的Activity,除非這個獨特的任務棧被系統銷燬了code

TaskAffinity

好了,如今要開始介紹TaskAffinity了,若是單獨設置TaskAffinity屬性的話是沒有任何效果的,只有Activity的launchMode設置成singTask的時候纔會生效的。那麼如今咱們就來驗證一下:cdn

這裏須要注意的是:
1.TaskAffinity的值應該是xxx.xxx.xxx相似包名的,若是沒有包括.的話是安裝不了的;   
2.若是不指定TaskAffinity的話,默認的值是包名。複製代碼
案例1

這裏的MainActivity中的代碼很簡單,就是把當前的類名和TaskId打印出來,SecondActivity和ThirdActivity也是同樣的。blog

輸出:
cn.xdeveloper.activitytest.MainActivity
698ip

cn.xdeveloper.activitytest.SecondActivity
698it

cn.xdeveloper.activitytest.ThirdActivity
698

這裏能夠看到這三個Activity的TaskId都相同,可見TaskAffinity屬性並無起做用。

案例2

修改SencondActivity的launchMode=singleTask。

輸出:

cn.xdeveloper.activitytest.MainActivity
699

cn.xdeveloper.activitytest.SecondActivity
700

cn.xdeveloper.activitytest.ThirdActivity
700

這裏能夠看到SecondActivity的TaskId改變了,啓動Activity的時候會根據taskAffinity查找是否有存在的任務棧,沒有的話就建立一個新的任務棧。同時在啓動ThirdActivity,也會加入到當前的任務棧中。

案例3

修改SencondActivity的launchMode=singleInstance,其餘不變。

輸出:

cn.xdeveloper.activitytest.MainActivity
703

cn.xdeveloper.activitytest.SecondActivity
704

cn.xdeveloper.activitytest.ThirdActivity
703

能夠看到SecondActivity是建立在新的棧裏,而ThirdActivity卻仍是建立在原來的棧裏面,這是由於singleInstance的特性形成的,它會建立一個新的棧而且裏邊就只有一個Activity實例,因此和singTask不一樣,以後啓動的ThirdActivity不會進入到該棧中。

其實這裏SecondActivity中設置的taskAffinity是沒意義的,就算不設置結果也是同樣的,由於singleInstance會建立一個新的棧並只能保存惟一的Activity,因此其餘的Activity就算設置了同樣的taskAffinity也不起做用了。

這裏講一下啓動過程:
MainActivity(703棧進入前臺) --> SecondActivity(704棧進入前臺,703棧進入後臺) --> ThirdActivity(703棧進入前臺,704棧進入後臺)

最終棧裏的狀況是:
前臺:703棧(ThirdActivity、MainActivity)
後臺:702棧(SecondActivity)

因此這個時候依次點擊返回鍵退回的話:
ThirdActivity --> MainActivity --> SecondActivity

總結

到這裏TaskAffinity的做用已經很明瞭了,經過這個屬性能夠把不一樣的Activity分在不一樣的任務棧中,這裏總結一下重點:

1.TaskAffinity屬性只有在launchMode=singleTask的時候纔有做用;(案例一、案例2)2.正常狀況下啓動的Activity會默認加到當前的前臺棧中;(案例2)

相關文章
相關標籤/搜索