標籤:android style class blog code http
Android中Task是一個邏輯上的概念,簡單地說,就是一個棧裡面順序儲存著的多個Activity。這些Activity能夠是來自同一個App,也能夠是來自不同的Apps。
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中。
上面的這個流程例如以所看到的:
這種一系列Activity的順序組合,在Android中的概念就是一個Task。通俗地說,它表示了一個App順序提供的功能展示,包含其調用其它App的功能。
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的Team Dev並不建議這樣做,由於大多數的情況下,運用預設的機制已經能夠非常好滿足App的須要。
Launch ModeLaunch Mode是Android提供的在AndroidManifest中,<activity>元素上所提供的屬性,它有下面四個值:
1)standard 這是launcher Mode的預設值,也就是上述的情況。
2)singleTopSingleTop是為了保證同樣的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都清除掉。
結束。