1. 程式人生 > >Activity的啟動模式、任務棧以及使用場景

Activity的啟動模式、任務棧以及使用場景

Activity的啟動模式、任務棧以及使用場景
目錄
  • Activity
  • 生命週期
  • 任務棧
  • 啟動模式
  • Intent Flag
  • taskAffinity屬性
一、 Activity作為最常用的四大元件之一,肯定都很熟悉其基本用法了。這裡就不寫介紹了。 二、 生命週期: 官方介紹的Activity生命週期圖.。
下面開始講解: 先提前把Activity的四種啟動模式說一下: manifest 中對應註冊Activity下
android:launchMode="standard" ①standard(預設) ②singleTop ③singleTask ④singleInstance (1)、第一種情況:正常的啟動一個Activity 啟動: 退出: (2)開啟並按下home鍵 再重新開啟:
(3)在開啟FourActivity情況下再打開個Dialog的Activity DiaLog樣式的FiveActivity消失

(4)重新開啟按下選單鍵(會進到多工 概覽螢幕 的一個介面) 再點選進入 退出 (5)重新開啟然後切換成橫屏 接著橫屏切換回豎屏 當切換成橫屏或者豎屏時都會走完Activity的生命週期重新建立一個Activity 但會在 onSaveInstanceState 儲存資料在 onRestoreInstanceState 裡取資料出來進行操作
ConfigChanges
,用於捕獲手機狀態的改變。在Activity中添加了android:configChanges屬性,在當所指定屬性(Configuration Changes)發生改變時,通知程式呼叫onConfigurationChanged()函式。 對Activity設定 android :configChanges= "orientation|keyboardHidden"
重新開啟然後切換成橫屏 接著橫屏切換回豎屏

三、任務棧 Activity的任務棧和啟動模式相關: 一、standard模式: 一、在FourActivity中啟動FourActivity: 退出
結論: standard( 標準模式),每次啟動都會建立一個新的Activity例項(在不指定啟動模式的情況下都是預設以此種方式啟動的),覆蓋在原有的Activity上,原有的Activity入棧。 二、singleTop模式: 一、在FourActivity中啟動FourActivity 退出:
二、 FourActivity中啟動FiveActivity--->啟動FourActivity FourActivity-->FiveActivity FiveActivity-->FourActivity 退出:
結論: singleTop 此種模式下,Activity在啟動時會進行判斷,如果當前的App的棧頂的Activity即就是將要啟動的Activity,那麼就不會建立新的例項,直接使用棧頂的例項。
三、singleTask模式: 一、FourActivity中啟動FiveActivity--->啟動FourActivity FourActivity-->FiveActivity FiveActivity-->FourActivity 退出
結論: singleTask 如果是同一個App中啟動某個設定了此模式的Activity的話,如果棧中已經存在該Activity的例項,那麼就會將該Activity上面的Activity清空,並將此例項放在棧頂。
四、 singleInstance 一、FourActivity-->啟動FourActivity 重新開啟FourActivity 再次開啟FourActivity 退出 二、FourActivity-->FiveActivity-->FourActivity-->FourActivity-->退出 FourActivity-->FiveActivity FiveActivity-->FourActivity FourActivity-->FourActivity 退出
結論: singleInstance 這個模式就很好記,以此模式啟動的Activity會存放在一個單獨的任務棧中,且只會有一個例項。
四、Intent Flag設定啟動模式 Intent物件大致包含Component、Action、Category、Data、Type、Extra和Flag這7種屬性,其中Intent的Flag屬性用於為該Intent新增一些額外的控制旗標,可以通過Intent的addFlags方法為Intent新增控制旗標。 一、跟Activity跳轉有關的Flag旗杆(這裡說可能比較常用的,其他的碼友可以去看下原始碼解釋) 1、 FLAG_ACTIVITY_NEW_TASK 預設啟動旗標,該旗標控制建立一個新的Activity例項,該Flag相當於Activity啟動模式中的standard。 2 FLAG_ACTIVITY_CLEAR_TOP 清除當前Activity之上的所有例項,該Flag相當於Activity啟動模式中的singleTask,例如,一個Activity棧中包含有A、B、C、D ,4個Activity例項,當在Activity D中以該旗標啟動Activity B時,此時Activity棧中只包含A、B兩個Activity例項。 3、 FLAG_ACTIVITY_SINGLE_TOP 從名字中不難看出該Flag相當於Activity載入模式中的singleTop模式,即原來Activity棧中有A、B、C、D這4個Activity例項,當在Activity D中再次啟動Activity D時,Activity棧中依然還是A、B、C、D這4個Activity例項。 4、 FLAG_ACTIVITY_NO_HISTORY 如名字不存在的歷史的標誌,以該旗標啟動的Activity不會保留在Activity棧中,如:Activity棧中有A、B兩個Activity例項,當在Activity B中以該旗標啟動Activity C,在Activity C中再啟動Activity D,此時Activity棧中只有A、B、D三個Activity例項,即Activity C不會保留在Activity棧中。 5、 FLAG_ACTIVITY_REORDER_TO_FRONT 即如果棧中已有該Activity則直接將該Activity帶到前臺。如:Activity棧中有A、B、C、D四個Activity,如果在Activity D使用該旗標啟動Activity C,那麼啟動後Activity棧中的情形為:A-B-D-C。
五、taskAffinity taskAffinity 生效時,如已經存在相應名稱的任務棧,則不會新建棧,而是在該棧的棧頂建立相應activity;如果沒有相應名稱的任務棧,就會建立對應名稱的新的任務棧。 (setFlags和addFlags的區別是:setFlags會直接將原來的Flag直接替換掉;而addFlags是將引數新增上去。) 而控制activity所屬的任務棧。不過只設置這一個屬性是不能完成功能的,需要與其它屬性相配合。
一、通過配置方式來實現TaskAffinity來實現 使TaskAffinity屬性生效,要與其它屬性相配合。在配置檔案中,需要設定activity的啟動模式為singleTask或singleInstance才能生效(其實singleInstance本來就會在新Task中)。
二.通過動態的方式實現TaskAffinity屬性 通過上述的配置,可以實現TaskAffinity屬性。但是這樣每次啟動該Activity都會在TaskAffinity指定的棧中啟動。有時候可能會希望該activity在特殊情況下才在TaskAffinity指定的棧中啟動,大部分時候還是在原有的任務棧中啟動,這個時候就需要動態方式來實現TaskAffinity屬性。  在配置檔案中,只制定TaskAffinity屬性,而不制定launchMode的屬性為singleTask。 < activity android:name=".FourActivity" android:taskAffinity="taskName"/> 這樣通過正常方式啟動該Activity時,該Activity就會在原有任務棧中啟動(啟動該Activity的任務棧中)。若想在taskAffinity屬性生效,需要在啟動該Activity時設定Flag為FLAG_ACTIVITY_NEW_TASK。 Intent intent = new Intent(aAvtivity.this, bActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);
六、使用場景 一、當Activity使用singleTop或者SingleTask啟動模式時,且要啟動的Activity剛好在棧頂。 例如:A時搜尋資料的頁面 B->搜尋結果列表頁面。每次都會退到A搜尋再回到B->則會多次建立B。所以A放入B中整合時又想讓Intent的資料再B中是不行的。因此就出現了 onNewIntent()方法。 官方解釋如下:
  • /**
* This is called for activities that set launchMode to "singleTop" in their package or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} * flag when calling {@link #startActivity}. In either case, when the * activity is re-launched while at the top of the activity stack instead * of a new instance of the activity being started, onNewIntent() will be * called on the existing instance with the Intent that was used to * re-launch it. * <p>An activity will always be paused before receiving a new intent, so * you can count on {@link #onResume} being called after this method. * <p>Note that {@link #getIntent} still returns the original Intent. You * can use {@link #setIntent} to update it to this new Intent. * @param intent The new intent that was started for the activity. * @see #getIntent * @see #setIntent * @see #onResume */ 而使用 getIntent 方法獲取到的依舊是以前的Intent,可以通過setIntent方法設定新的Intent。方法引數就是新傳遞的Intent.。又可以再Intent獲取資料。
二、App中Activity過多不好管理。 可以針對App的業務場景封裝一個AppActivityManager管理類,用於管理Activity,可以在退出App時候銷燬所有Activity。
暫且聊到此,有什麼不對的歡迎指出。謝謝你的閱讀。