Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android的Task和Activity相關

Android的Task和Activity相關

編輯:關於Android編程

android:allowTaskReparenting     用來標記Activity能否從啟動的Task移動到有著affinity的Task(當這個Task進入到前台時)——“true”,表示能移動,“false”,表示它必須呆在啟動時呆在的那個Task裡。     如果這個特性沒有被設定,設定到<application>元素上的allowTaskReparenting特性的值會應用到Activity上。默認值為“false”。     一般來說,當Activity啟動後,它就與啟動它的Task關聯,並且在那裡耗盡它的整個生命周期。當當前的Task不再顯示時,你可以使用這個特性來強制Activity移動到有著affinity的Task中。典型用法是:把一個應用程序的Activity移到另一個應用程序的主Task中。     例如,如果e-mail中包含一個web頁的鏈接,點擊它就會啟動一個Activity來顯示這個頁面。這個Activity是由Browser應用程序定義的,但是,現在它作為e-mail Task的一部分。如果它重新宿主到Browser Task裡,當Browser下一次進入到前台時,它就能被看見,並且,當e-mail Task再次進入前台時,就看不到它了。     Actvity的affinity是由taskAffinity特性定義的。Task的affinity是通過讀取根Activity的affinity決定。因此,根據定義,根Activity總是位於相同affinity的Task裡。由於啟動模式為“singleTask”和“singleInstance”的Activity只能位於Task的底部,因此,重新宿主只能限於“standard”和“singleTop”模式。   android:alwaysRetainTaskState     用來標記Activity所在的Task的狀態是否總是由系統來保持——“true”,表示總是;“false”,表示在某種情形下允許系統恢復Task到它的初始化狀態。默認值是“false”。這個特性只針對Task的根Activity有意義;對其它Activity來說,忽略之。     一般來說,特定的情形如當用戶從主畫面重新選擇這個Task時,系統會對這個Task進行清理(從stack中刪除位於根Activity之上的所有Activivity)。典型的情況,當用戶有一段時間沒有訪問這個Task時也會這麼做,例如30分鐘。     然而,當這個特性設為“true”時,用戶總是能回到這個Task的最新狀態,無論他們是如何啟動的。這非常有用,例如,像Browser應用程序,這裡有很多的狀態(例如多個打開的Tab),用戶不想丟失這些狀態。   android:clearTaskOnLaunch     用來標記是否從Task中清除所有的Activity,除了根Activity外(每當從主畫面重新啟動時)——“true”,表示總是清除至它的根Activity,“false”表示不。默認值是“false”。這個特性只對啟動一個新的Task的Activity(根Activity)有意義;對Task中其它的Activity忽略。     當這個值為“true”,每次用戶重新啟動這個Task時,都會進入到它的根Activity中,不管這個Task最後在做些什麼,也不管用戶是使用BACK還是HOME離開的。當這個值為“false”時,可能會在一些情形下(參考alwaysRetainTaskState特性)清除Task的Activity,但不總是。     假設,某人從主畫面啟動了Activity P,並從那裡遷移至Activity Q。接下來用戶按下HOME,然後返回Activity P。一般,用戶可能見到的是Activity Q,因為它是P的Task中最後工作的內容。然而,如果P設定這個特性為“true”,當用戶按下HOME並使這個Task再次進入前台時,其上的所有的Activity(在這裡是Q)都將被清除。因此,當返回到這個Task時,用戶只能看到P。     如果這個特性和allowTaskReparenting都設定為“true”,那些能重新宿主的Activity會移動到共享affinity的Task中;剩下的Activity都將被拋棄,如上所述。   android:finishOnTaskLaunch     用來標記當用戶再次啟動它的Task(在主畫面選擇這個Task)時已經存在的Activity實例是否要關閉(結束)——“true”,表示應該關閉,“false”表示不關閉。默認值是“false”。     如果這個特性和allowTaskReparenting都設定為“true”,這個特性勝出。Activity的affinity忽略。這個Activity不會重新宿主,但是會銷毀。   android:launchMode     用於指示Activity如何啟動。這裡有四種模式,與Intent對象中的Activity Flags(FLAG_ACTIVITY_*變量)共同作用,來決定Activity如何啟動來處理Intent。它們是:       "standard"     "singleTop"     "singleTask"     "singleInstance"       默認模式是“standard”。          這些模式可以分成兩大組別,“standard”和“singleTop”一組,“singleTask”和“singleInstance”一組。具有“standard”和“singleTop”啟動模式的Activity可以實例化很多次。這些實例可以屬於任何Task並且可以位於Activity stack的任何位置。典型的情況是,它們會進入調用startActivity()的Task(除非Intent對象包含FLAG_ACTIVITY_NEW_TASK標志,在這種情況下會選擇一個不同的Task——參考taskAffinity特性)。     相反的,“singleTask”和“singleInstance”只能啟動一個Task。它們總是位於Activity stack的底部。甚至,設備一次只能擁有一個Activity的實例——只有一個這樣的Task。     “standard”和“singleTop”模式只在一種情況下有差別:每次有一個新的啟動“standard”Activity的Intent,就會創建一個新的實例來響應這個Intent。每個實例處理一個Intent。相似的,一個“singleTop”的Activity實例也有可能被創建來處理新的Intent。然而,如果目標Task已經有一個存在的實例並且位於stack的頂部,那麼,這個實例就會接收到這個新的Intent(調用onNewIntent());不會創建新的實例。在其他情況下——例如,如果存在的“singleTop”的Activity實例在目標Task中,但不是在stack的頂部,或者它在一個stack的頂部,但不是在目標Task中——新的實例都會被創建並壓入stack中。     “singleTask”和“singleInstance”模式也只在一種情況下有差別:“singleTask”Activity允許其它Activity成為它的Task的部分。它位於Activity stack的底部,其它Activity(必須是“standard”和“singleTop”Activity)可以啟動加入到相同的Task中。“singleInstance”Activity,換句話說,不允許其它Activity成為它的Task的部分。它是Task中的唯一Activity。如果它啟動其它的Activity,這個Activity會被放置到另一個task中——好像Intent中包含了FLAG_ACTIVITY_NEW_TASK標志。   android:noHistory     用於標記當用戶從Activity上離開並且它在屏幕上不再可見時Activity是否從Activity stack中清除並結束(調用finish()方法)——“true”,表示它應該關閉,“false”,表示不需要。默認值是“false”。     “true”值意味著Activity不會留下歷史痕跡。因為它不會在Activity stack的Task中保留,因此,用戶不能返回它。   android:taskAffinity    Activity為Task擁有的一個affinity。擁有相同的affinity的Activity理論上屬於相同的Task(在用戶的角度是相同的“應用程序”)。Task的affinity是由它的根Activity決定的。     affinity決定兩件事情——Activity重新宿主的Task(參考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK標志啟動的Activity宿主的Task。     默認情況,一個應用程序中的所有Activity都擁有相同的affinity。捏可以設定這個特性來重組它們,甚至可以把不同應用程序中定義的Activity放置到相同的Task中。為了明確Activity不宿主特定的Task,設定該特性為空的字符串。     如果這個特性沒有設置,Activity將從應用程序的設定那裡繼承下來(參考<application>元素的taskAffinity特性)。應用程序默認的affinity的名字是<manifest>元素中設定的package名。   FLAG_ACTIVITY_BROUGHT_TO_FRONT      這個標志一般不是由程序代碼設置的,如在launchMode中設置singleTask模式時系統幫你設定。   FLAG_ACTIVITY_CLEAR_TOP     如果設置,並且這個Activity已經在當前的Task中運行,因此,不再是重新啟動一個這個Activity的實例,而是在這個Activity上方的所有Activity都將關閉,然後這個Intent會作為一個新的Intent投遞到老的Activity(現在位於頂端)中。     例如,假設一個Task中包含這些Activity:A,B,C,D。如果D調用了startActivity(),並且包含一個指向Activity B的Intent,那麼,C和D都將結束,然後B接收到這個Intent,因此,目前stack的狀況是:A,B。     上例中正在運行的Activity B既可以在onNewIntent()中接收到這個新的Intent,也可以把自己關閉然後重新啟動來接收這個Intent。如果它的啟動模式聲明為“multiple”(默認值),並且你沒有在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標志,那麼它將關閉然後重新創建;對於其它的啟動模式,或者在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標志,都將把這個Intent投遞到當前這個實例的onNewIntent()中。     這個啟動模式還可以與FLAG_ACTIVITY_NEW_TASK結合起來使用:用於啟動一個Task中的根Activity,它會把那個Task中任何運行的實例帶入前台,然後清除它直到根Activity。這非常有用,例如,當從Notification Manager處啟動一個Activity。   FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET     如果設置,這將在Task的Activity stack中設置一個還原點,當Task恢復時,需要清理Activity。也就是說,下一次Task帶著FLAG_ACTIVITY_RESET_TASK_IF_NEEDED標記進入前台時(典型的操作是用戶在主畫面重啟它),這個Activity和它之上的都將關閉,以至於用戶不能再返回到它們,但是可以回到之前的Activity。     這在你的程序有分割點的時候很有用。例如,一個e-mail應用程序可能有一個操作是查看一個附件,需要啟動圖片浏覽Activity來顯示。這個Activity應該作為e-mail應用程序Task的一部分,因為這是用戶在這個Task中觸發的操作。然而,當用戶離開這個Task,然後從主畫面選擇e-mail app,我們可能希望回到查看的會話中,但不是查看圖片附件,因為這讓人困惑。通過在啟動圖片浏覽時設定這個標志,浏覽及其它啟動的Activity在下次用戶返回到mail程序時都將全部清除。   FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS     如果設置,新的Activity不會在最近啟動的Activity的列表中保存。   FLAG_ACTIVITY_FORWARD_RESULT     如果設置,並且這個Intent用於從一個存在的Activity啟動一個新的Activity,那麼,這個作為答復目標的Activity將會傳到這個新的Activity中。這種方式下,新的Activity可以調用setResult(int),並且這個結果值將發送給那個作為答復目標的Activity。   FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY      這個標志一般不由應用程序代碼設置,如果這個Activity是從歷史記錄裡啟動的(常按HOME鍵),那麼,系統會幫你設定。   FLAG_ACTIVITY_MULTIPLE_TASK      不要使用這個標志,除非你自己實現了應用程序啟動器。與FLAG_ACTIVITY_NEW_TASK結合起來使用,可以禁用把已存的Task送入前台的行為。當設置時,新的Task總是會啟動來處理Intent,而不管這是是否已經有一個Task可以處理相同的事情。     由於默認的系統不包含圖形Task管理功能,因此,你不應該使用這個標志,除非你提供給用戶一種方式可以返回到已經啟動的Task。     如果FLAG_ACTIVITY_NEW_TASK標志沒有設置,這個標志被忽略。   FLAG_ACTIVITY_NEW_TASK      如果設置,這個Activity會成為歷史stack中一個新Task的開始。一個Task(從啟動它的Activity到下一個Task中的Activity)定義了用戶可以遷移的Activity原子組。Task可以移動到前台和後台;在某個特定Task中的所有Activity總是保持相同的次序。     這個標志一般用於呈現“啟動”類型的行為:它們提供用戶一系列可以單獨完成的事情,與啟動它們的Activity完全無關。     使用這個標志,如果正在啟動的Activity的Task已經在運行的話,那麼,新的Activity將不會啟動;代替的,當前Task會簡單的移入前台。參考FLAG_ACTIVITY_MULTIPLE_TASK標志,可以禁用這一行為。     這個標志不能用於調用方對已經啟動的Activity請求結果。   FLAG_ACTIVITY_NO_ANIMATION      如果在Intent中設置,並傳遞給Context.startActivity()的話,這個標志將阻止系統進入下一個Activity時應用Acitivity遷移動畫。這並不意味著動畫將永不運行——如果另一個Activity在啟動顯示之前,沒有指定這個標志,那麼,動畫將被應用。這個標志可以很好的用於執行一連串的操作,而動畫被看作是更高一級的事件的驅動。   FLAG_ACTIVITY_NO_HISTORY      如果設置,新的Activity將不再歷史stack中保留。用戶一離開它,這個Activity就關閉了。這也可以通過設置noHistory特性。   FLAG_ACTIVITY_NO_USER_ACTION      如果設置,作為新啟動的Activity進入前台時,這個標志將在Activity暫停之前阻止從最前方的Activity回調的onUserLeaveHint()。     典型的,一個Activity可以依賴這個回調指明顯式的用戶動作引起的Activity移出後台。這個回調在Activity的生命周期中標記一個合適的點,並關閉一些Notification。     如果一個Activity通過非用戶驅動的事件,如來電或鬧鐘,啟動的,這個標志也應該傳遞給Context.startActivity,保證暫停的Activity不認為用戶已經知曉其Notification。   FLAG_ACTIVITY_PREVIOUS_IS_TOP      If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately.    FLAG_ACTIVITY_REORDER_TO_FRONT     如果在Intent中設置,並傳遞給Context.startActivity(),這個標志將引發已經運行的Activity移動到歷史stack的頂端。     例如,假設一個Task由四個Activity組成:A,B,C,D。如果D調用startActivity()來啟動Activity B,那麼,B會移動到歷史stack的頂端,現在的次序變成A,C,D,B。如果FLAG_ACTIVITY_CLEAR_TOP標志也設置的話,那麼這個標志將被忽略。   FLAG_ACTIVITY_RESET_TASK_IF_NEEDED   If set, and this activity is either being started in a new task or bringing to the top an existing task, then it will be launched as the front door of the task. This will result in the application of any affinities needed to have that task in the proper state (either moving activities to or from it), or simply resetting that task to its initial state if needed.    FLAG_ACTIVITY_SINGLE_TOP     如果設置,當這個Activity位於歷史stack的頂端運行時,不再啟動一個新的。    Activity和Task   之前提到的,一個Activity可以啟動另一個,即便是定義在不同應用程序中的Activity。例如,假設你想讓用戶顯示一些地方的街景。而這裡已經有一個Activity可以做到這一點,因此,你的Activity所需要做的只是在Intent對象中添加必要的信息,並傳遞給startActivity()。地圖浏覽將會顯示你的地圖。當用戶按下BACK鍵,你的Activity會再次出現在屏幕上。   對於用戶來說,看起來好像是地圖浏覽與你的Activity一樣,屬於相同的應用程序,即便是它定義在其它的應用程序裡,並運行在那個應用程序的進程裡。Android通過將這兩個Activity保存在同一個Task裡來體現這一用戶體驗。簡單來說,一個Task就是用戶體驗上的一個“應用”。它將相關的Activity組合在一起,以stack的方式管理。stack中根Activity啟動Task——典型的,它就是用戶在應用程序啟動欄中選擇的Activity。位於stack頂端的Activity是當前正在運行的——能夠聚焦用戶的動作。當一個Activity啟動另一個,新的Activity進入stack;它成為正在運行的Activity。之前的Activity仍保留在stack中。當用戶按下BACK鍵,當前的Activity從stack中退出,之前的那個成為正在運行的Activity。   stack包含對象,因此,如果一個Task中有多個同一個Activity的實例時——多個地圖浏覽,例如——stack為每個實例擁有一個獨立的入口。位於stack中的Activity不會重新調整,只是進入和退出。   一個Task就是一組Activity,不是一個類或者在manifest中定義的一個元素。因此,沒有辦法為Task設置獨立於它的Activity的屬性值。Task的值作為整體在根Activity中設置。例如,下一個章節會討論Task的“affinity”;那個值就是從Task中的根Activity中讀取的。   Task中的所有Activity作為一個單元一起移動。整個Task(整個Activity stack)可以進入前台或者退到後台。例如,假設當前Task中的stack中有4個Activity——3個位於當前Activity下方。用戶按下HOME鍵,進入到應用程序啟動欄,然後選擇一個新的應用程序(實際上,一個新的Task)。當前Task退到後台,並且新Task中的根Activity會顯示出來。然後,經過一段時間後,用戶回到Home畫面,然後再次選擇前一個應用程序(前一個Task)。那個擁有4個Activity的Task會進入前台。當用戶按下BACK鍵,屏幕不會顯示用戶剛剛離開的Activity(前一個Task的根Activity)。而是,這個stack中的頂端Activity移除,相同Task中的前一個Activity會顯示出來。   剛才描述的行為是Activity和Task的默認行為。但有方法來完全改變它。Task之間的關聯,和一個Task中的一個Activity行為,受啟動Activity的Intent對象中設置的Flag和manifest文件中Activity的<activity>元素的特性值交互控制。調用者和響應者都有權決定如何發生。   核心的Intent Flag有: FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_SINGLE_TOP   核心的<activity>特性有: taskAffinity launchMode allowTaskReparenting clearTaskOnLaunch alwaysRetainTaskState finishOnTaskLaunch   接下來的章節將描述一些Flag和特性的用法,如何相互影響,以及在使用時的建議。   Affinity和新Task 默認情況下,一個應用程序中的所有Activity都有affinity——也就是說,屬於同一個Task中所有Activity有一個設定。然而,每個Activity都可以在<activity>元素的taskAffinity特性上設置單獨的值。定義在不同應用程序中的Activity可以共享同一個affinity,或者定義在同一個應用程序中的Activity設置不同的affinity。Affinity在兩種環境下工作:Intent對象包含FLAG_ACTIVITY_NEW_TASK標志,和Activity的allowTaskReparenting特性設置為“true”。 FLAG_ACTIVITY_NEW_TASK: 之前描述的,一個Activity一般通過調用startActivity()啟動並加入到Task中。它同調用者一樣,進入同一個Task。然而,如果傳遞給startActivity()的Intent對象中包含FLAG_ACTIVITY_NEW_TASK時,系統會搜索一個新的Task來容納新的Activity。通常,如標志的名字所示,是一個新的Task。然而,並不是必須是。如果已經存在一個Task與新Activity的affinity相同,這個Activity就會加入到那個Task中。如果不是,啟動一個新的Task。 allowTaskReparenting: 如果一個Activity的allowTaskReparenting特性設置為“true”,它就能從啟動的Task中移到有著相同affinity的Task(這個Task進入到前台的時候)。例如,在一個旅游的程序中定義了一個可以報告選擇城市的天氣情況的Activity。它和同一個應用程序的其它Activity一樣,有著相同的Affinity(默認的Affinity),並且它允許重新宿主。你的Activity中的一個啟動了天氣預報,因此,它初始化到和你Activity相同的Task中。然而,當旅游應用程序下一次進入到前台時,天氣預報那個Activity將會重新編排並在那個Task中顯示。   如果從用戶的角度出發,一個.apk文件包含多個“應用”的話,你可能希望為關聯的Activity設置不同的affinity。   Launch Mode   這裡4種不同的啟動模式可以設置到<activity>元素的launchMode特性上: standard(默認模式) singleTop singleTask singleInstance   這些模式有以下四點區別: l  哪個Task將容納響應Intent的Activity。對於“standard”和“singleTop”來說,是產生Intent的那個Task(並調用startActivity())——除非Intent對象包含FLAG_ACTIVITY_NEW_TASK。在那種情況下,不同的Task將被選擇,如“Affinity和新Task”中描述的那樣。對比而言,“singleTask”和“singleInstance”指示Activity總是一個Task的根。它們定義一個Task;它們不會加入到另一個Task中。   l  是否有多個Activity的實例。“standard”和“singleTop”可以實例化多次。它們可以屬於多個Task,一個特定的Task可以有相同Activity的多個實例。對比而言,“singleTask”和“singleInstance”只能有一個實例。因為這些Activity只能位於Task的底部,這一限制意味著在設備的某個時間,不會出現這樣Task的多個實例。   l  是否可以在同一個Task中擁有其它的Activity。“singleInstance”Activity保持單身,在它的Task中它是僅有的Activity。如果它啟動另一個Activity,那個Activity將會放入到不同的Task中,而不管它的啟動模式——好像FLAG_ACTIVITY_NEW_TASK在Intent中一樣。對於其它方面,,“singleInstance”等同於“singleTask”。其它三個模式允許多個Activity加入到這個Task中。“singleTask”Activity總是位於Task的底部,但它可以啟動其它的Activity並放入到它的Task中。“standard”和“singleTop”的Activity可以出現在stack的任何地方。   l  是否一個新的實例啟動來處理新的Intent。對於默認的“standard”來說,都是創建一個新的實例來響應新的Intent。每個實例處理一個Intent。對於“singleTop”來說,如果它位於目標Task的頂端,那麼,已經存在的實例就可以重復使用來處理這個新的Intent。如果它不在頂端,那麼它就不能重復使用。替代的,新的實例將創建來響應新的Intent,並進入到stack中。   例如,假設一個Task的Activity stack中包含根Activity A和其它Activity B,C,D,並且D位於頂端,因此,stack是A-B-C-D。有一個Intent來了,它要啟動D類型的Activity。如果D有默認的“standard”啟動模式,那麼,一個新的實例將被啟動並且stack變成A-B-C-D-D。然而,如果D的啟動模式“singleTop”,已經存在的實例將去處理新來的Intent(因為它正好處在stack的頂端),並且stack依舊是A-B-C-D。 換句話說,如果來臨的Intent是沖著B類型的,那麼,B類型的實例將被創建啟動而不管B的模式是“standard”或“singleTop”(因為B不處在stack的頂端),因此,stack將會是A-B-C-D-B。 之前提到的,設備上不會出現超過一個實例的“singleTask”或“singleInstance”Activity,因此,那個實例都將去處理所有新來的Intent。“singleInstance alimama_pid="mm_15626785_2176297_8615857"; alimama_titlecolor="3366CC"; alimama_descolor ="000000"; alimama_bgcolor="FFFFFF"; alimama_bordercolor="CCCCCC"; alimama_linkcolor="008000"; alimama_bottomcolor="FFFFFF"; alimama_anglesize="0"; alimama_bgpic="0"; alimama_icon="0"; alimama_sizecode="9999"; alimama_width=468; alimama_height=90; alimama_type=2;  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved