其實一直以來都知道在AndroidManifest的Activity中能夠配置TaskAffinity這個屬性,只知道這個東西和Activity的任務棧有關,今天花了點時間好好學習了一些這個東西。javascript
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屬性的話是沒有任何效果的,只有Activity的launchMode設置成singTask的時候纔會生效的。那麼如今咱們就來驗證一下:cdn
這裏須要注意的是:
1.TaskAffinity的值應該是xxx.xxx.xxx相似包名的,若是沒有包括.的話是安裝不了的;
2.若是不指定TaskAffinity的話,默認的值是包名。複製代碼
這裏的MainActivity中的代碼很簡單,就是把當前的類名和TaskId打印出來,SecondActivity和ThirdActivity也是同樣的。blog
輸出:
cn.xdeveloper.activitytest.MainActivity
698ip
cn.xdeveloper.activitytest.SecondActivity
698it
cn.xdeveloper.activitytest.ThirdActivity
698
這裏能夠看到這三個Activity的TaskId都相同,可見TaskAffinity屬性並無起做用。
修改SencondActivity的launchMode=singleTask。
輸出:
cn.xdeveloper.activitytest.MainActivity
699
cn.xdeveloper.activitytest.SecondActivity
700
cn.xdeveloper.activitytest.ThirdActivity
700
這裏能夠看到SecondActivity的TaskId改變了,啓動Activity的時候會根據taskAffinity查找是否有存在的任務棧,沒有的話就建立一個新的任務棧。同時在啓動ThirdActivity,也會加入到當前的任務棧中。
修改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)