Task的創建
比方之前的一個Todo List的Demo,當它被安裝到手機上之后,在應用程序列表,也即Launcher中,會有一個圖標顯示,假設長按這個圖標,還能為其在桌面上創建一個快捷方式。當點擊這個圖標,或者快捷方式,Todo List中入口的Main Activity就會被創建,而與此同一時候,一個Stack也會被創建,然后,Activity會被放到這個Stack中。
當Main Activity,點擊列表項,Detail Activity會創建,也被放到Stack中。
當在Detail Activity中點擊“查看圖片”進入Image Activity,Image Activity也被放入Stack中,
而當Image Activity,通過Intent,調用系統中另外一個App(照相機)去獲取照片時,它調用的事實上是照相機App中的一個Activity,在默認這個情況下,這個Activity也是被放在當前的Stack中。
上面的這個流程例如以下圖所看到的:
Task的結束
而當用戶點擊Back鍵,或者ActionBar上的返回鍵的時候,當前的Activity就會從Stack中被彈出來,然后銷毀,這樣一直返回,最后最開始的Activity,在上例中是Main Activty,也會被從stack中彈出來,並消毀,而結果就是回到桌面上,當最后一個Activity從stack中退出的時候,stack也被銷毀了,那么一個Task也就沒有存在的意義了。
那么此時就不存在Task了。
Task的切換
所以從Launcher中或者快捷方式啟動一個App的時候,假設這個App近期沒有被啟動過,那么就會創建一個新的Stack,從而啟動一個新的Task。Home應用,也是一個Task,當用戶點擊Home鍵的時候,屏幕就會跑到桌面,也就是說,當前的Task被停止了,而切換到了Home所在的Task。
此時,原來顯示在屏幕上的Task就會被轉移到后台,在用戶看不見的屏幕的深處,在那里,Task中的全部Activity都會處於stop狀態,可是全部的內容和狀態都會被保存。
當從Launcher中,或者快捷方式,再去點擊應用的圖標的時候,處於后台的Task又會被帶到屏幕上顯示,用戶能夠繼續操作,而Home應用所在的Task就被切換到后台。
所以在用戶看着屏幕的時候,在屏幕后面那些不可見的虛擬空間中,可能同一時候存在着多個Task,靜靜地呆着,等待着隨時被帶到屏幕上展示。
上面所述的處理,都是在Android中默認的情況下發生的。在這樣的情況下,當創建一個Activity,就會往Stack中放一個Activity,當返回上一個Activity,當前的Activity就會被移除
並消毀,而Task能夠同一時候存在多個同樣的Activity。
當然,Android也提供了一些屬性或者標志來讓用戶去改動默認的處理行為,盡管Android的開發團隊並不建議這樣做,由於大多數的情況下,運用默認的機制已經能夠非常好滿足App的須要。
Launch Mode
Launch Mode是Android提供的在AndroidManifest中,<activity>元素上所提供的屬性,它有下面四個值:1)standard
這是launcher Mode的默認值,也就是上述的情況。2)singleTop
SingleTop是為了保證同樣的Activity,僅僅有一個實例處於Stack的頂端,比方,在默認情況下,假設Stack中的Activity是A->B->C->D,假設在D中又利用Intent打開一個D的Activity,那么Stack中就會是這種序列,A->B->C->D->D。假設在D的activity中設置以下的屬性,
android:launchMode="singleTop"那么就Intent就會被當前Activity(即D)的onNewIntent的方法接收然后進行處理,那么在
Stack中的序列就還是跟原來一樣,即 A->B->C->D。
而在實際中的樣例,就有可能存在這樣一種情況,在ListView上高速地點擊Listitem,由於沒有處理DoubleClick事件,或者自己改寫了onTouch事件,那么可能這兩次點擊都會觸發
同一個itemClick事件,從而導致打開兩個相同的Activity,如 A->B->B,那么在B中回退的時候,發現還是回到B,要再返回一次才是回到A,那效果就會非常詭異了。
這種情況下,就能夠通過singleTop屬性來避免這種失誤。
3)singeTask
假設Activity中設置launchMode的屬性為SingleTask,則Activity會被創建的時候,首先會檢查有沒有存在一個Task中有這樣一個Activity,假設有的話,那么Android會直接將Intent路由到那個Activity,也是通過其onNewIntent方法進行處理,而假設不存在這種一個Task,那么Android會創建一個新的Stack,然后將Activity放進去作為Stack。
在這里會存在一種情況,假設已經存在一個Task中有這種一個Activty,假設這個Activity其上面還有Activity,即不是處於棧頂的話,那么其上面的Activity都會被銷毀。
而假設其以下還有Activity的話,它及它以下的全部Activity都會被帶到當前的Task中,也就是說,假設在這個Activity上面按返回鍵的話,返回的並非打開這個Activity的Activity,
而是其原先棧中以下的Activity。圖演示樣例如以下:
4)singleInstance
這樣的情況下跟SingleTask是一樣的,所不同的是其所創建的或者所尋找到的Task僅僅能有要啟動的Activity,且僅僅能有這么一個。上面四種情況是通過在AndroidManifest文件里設置activity的launchMode屬性的。
Intent Flag
在代碼中通過StartActivity來啟動下一個Activity的時候,能夠通過設置Intent的Flag來改動默認的Task管理標志,例如以下:Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Flag的值有下面三個:
1)FLAG_ACTIVITY_NEW_TASK
這個值跟LaunchMode中的SingleTask的效果是一樣的。2)FLAG_ACTIVITY_SINGLE_TOP
這個值跟LaunchMode中的SingleTop的效果是一樣的。3)Flag_ACTIVITY_CLEAR_TOP
當Intent設置了這樣一個標志,那么Android就會去尋找一個存在的Activity,假設找到了,其上面存在有其它Activity的話,就會將其上面的全部Activity都清除掉。
結束。