天天看點

[Android] 全面了解Activity Activity是什麼? Activity的内部調用過程 啟動模式 Intent Filter 開發中Activity的一些問題

官方文檔這麼說: 

an activity is a single, focused thing that the user can do. almost all activities interact with the user, so the activity class takes care of creating a window for you in which you can place your ui with setcontentview(view). 大概的意思(原諒我):   activity是獨立平等的,用來處理使用者操作。幾乎所有的activity都是用來和使用者互動的,是以activity類會建立了一個視窗,開發者可以通過setcontentview(view)的接口把ui放到給視窗上。

  android中的activity全都歸屬于task管理 。task 是多個 activity 的集合,這些 activity 按照啟動順序排隊存入一個棧(即“back stack”)。android預設會為每個app維持一個task來存放該app的所有activity,task的預設name為該app的packagename。

  當然我們也可以在androidmainfest.xml中申明activity的taskaffinity屬性來自定義task,但不建議使用,如果其他app也申明相同的task,它就有可能啟動到你的activity,帶來各種安全問題(比如拿到你的intent)。

  上面已經說了,系統通過堆棧來管理activity,當一個新的activity開始時,它被放置在堆棧的頂部和成為運作活動,以前的activity始終保持低于它在堆棧,而不會再次到達前台,直到新的活動退出。

  還是上這張官網的activity_lifecycle圖: 

[Android] 全面了解Activity Activity是什麼? Activity的内部調用過程 啟動模式 Intent Filter 開發中Activity的一些問題

 

首先打開一個新的activity執行個體的時候,系統會依次調用

oncreate() -> onstart() -> onresume() 然後開始running

  running的時候被覆寫了(從它打開了新的activity或是被鎖屏,但是它依然在前台運作, lost focus but is still visible),系統調用onpause();

 該方法執行activity暫停,通常用于送出未儲存的更改到持久化資料,停止動畫和其他的東西。但這個activity還是完全活着(它保持所有的狀态和成員資訊,并保持連接配接到視窗管理器)

接下來它有三條出路 

①使用者傳回到該activity就調用onresume()方法重新running

②使用者回到桌面或是打開其他activity,就會調用onstop()進入停止狀态(保留所有的狀态和成員資訊,對使用者不可見)

③系統記憶體不足,擁有更高限權的應用需要記憶體,那麼該activity的程序就可能會被系統回收。(回收onrause()和onstop()狀态的activity程序)要想重新打開就必須重新建立一遍。

如果使用者傳回到onstop()狀态的activity(又顯示在前台了),系統會調用

onrestart() -> onstart() -> onresume() 然後重新running

在activity結束(調用finish ())或是被系統殺死之前會調用ondestroy()方法釋放所有占用的資源。

activity生命周期中三個嵌套的循環

activity的完整生存期會在 oncreate() 調用和 ondestroy() 調用之間發生。 

activity的可見生存期會在 onstart() 調用和 onstop() 調用之間發生。系統會在activity的整個生存期内多次調用 onstart() 和onstop(), 因為activity可能會在顯示和隐藏之間不斷地來回切換。 

activity的前背景切換會在 onresume() 調用和 onpause() 之間發生。 

因為這個狀态可能會經常發生轉換,為了避免切換遲緩引起的使用者等待,這兩個方法中的代碼應該相當地輕量化。

onsaveinstancestate方法

  在activity 可能被回收之前 調用,用來儲存自己的狀态和資訊,以便回收後重建時恢複資料(在oncreate()或onrestoreinstancestate()中恢複)。旋轉螢幕重建activity會調用該方法,但其他情況在onrause()和onstop()狀态的activity不一定會調用 ,下面是該方法的文檔說明。

也就是說,系統靈活的來決定調不調用該方法,但是如果要調用就一定發生在onstop方法之前,但并不保證發生在onpause的前面還是後面。

onrestoreinstancestate方法

  這個方法在onstart 和 onpostcreate之間調用,在oncreate中也可以狀态恢複,但有時候需要所有布局初始化完成後再恢複狀态。

  onpostcreate:一般不實作這個方法,當程式的代碼開始運作時,它調用系統做最後的初始化工作。

   

簡單的說就是定義activity 執行個體與task 的關聯方式。 

   為了實作一些預設啟動(standard)模式之外的需求: 

讓某個 activity 啟動一個新的 task (而不是被放入目前 task )

讓 activity 啟動時隻是調出已有的某個執行個體(而不是在 back stack 頂建立一個新的執行個體) 

或者,你想在使用者離開 task 時隻保留根 activity,而 back stack 中的其它 activity 都要清空

  定義啟動模式的方法有兩種:

  在 manifest 檔案中activity聲明時,利用 activity 元素的 launchmode 屬性來設定 activity 與 task 的關系。

注意: 你用 launchmode 屬性為 activity 設定的模式可以被啟動 activity 的 intent 标志所覆寫。

“standard” (預設模式) 

  當通過這種模式來啟動activity時, android總會為目标 activity建立一個新的執行個體,并将該activity添加到目前task棧中。這種方式不會啟動新的task,隻是将新的 activity添加到原有的task中。  

“singletop” 

  該模式和standard模式基本一緻,但有一點不同:當将要被啟動的activity已經位于task棧頂時,系統不會重新建立目标activity執行個體,而是直接複用task棧頂的activity。

“singletask”

  activity在同一個task内隻有一個執行個體。 

如果将要啟動的activity不存在,那麼系統将會建立該執行個體,并将其加入task棧頂; 

  如果将要啟動的activity已存在,且存在棧頂,直接複用task棧頂的activity。 

  如果activity存在但是沒有位于棧頂,那麼此時系統會把位于該activity上面的所有其他activity全部移出task,進而使得該目标activity位于棧頂。

“singleinstance” 

  無論從哪個task中啟動目标activity,隻會建立一個目标activity執行個體且會用一個全新的task棧來裝載該activity執行個體(全局單例).

  如果将要啟動的activity不存在,那麼系統将會先建立一個全新的task,再建立目标activity執行個體并将該activity執行個體放入此全新的task中。

  如果将要啟動的activity已存在,那麼無論它位于哪個應用程式,哪個task中;系統都會把該activity所在的task轉到前台,進而使該activity顯示出來。

  在要啟動 activity 時,你可以在傳給 startactivity() 的 intent 中包含相應标志,以修改 activity 與 task 的預設關系。

flag_activity_new_task

  與”singletask”模式相同,在新的 task 中啟動 activity。如果要啟動的 activity 已經運作于某 task 中,則那個 task 将調入前台。

flag_activity_single_top

  與 “singletop”模式相同,如果要啟動的 activity位于back stack 頂,系統不會重新建立目标activity執行個體,而是直接複用task棧頂的activity。

flag_activity_clear_top

  此種模式在launchmode中沒有對應的屬性值。如果要啟動的 activity 已經在目前 task 中運作,則不再啟動一個新的執行個體,且所有在其上面的 activity 将被銷毀。

   一般不要改變 activity 和 task 預設的工作方式。 如果你确定有必要修改預設方式,請保持謹慎,并確定 activity 在啟動和從其它 activity 傳回時的可用性,多做測試和安全方面的工作。

  android的3個核心元件——activity、services、廣播接收器——是通過intent傳遞消息的。intent消息用于在運作時綁定不同的元件。 

在 android 的 androidmanifest.xml 配置檔案中可以通過 intent-filter 節點為一個 activity 指定其 intent filter,以便告訴系統該 activity 可以響應什麼類型的 intent。

  一個 intent filter 可以包含多個 action,action 清單用于标示 activity 所能接受的“動作”,它是一個使用者自定義的字元串。

在代碼中使用以下語句便可以啟動該intent 對象:

action 清單中包含了“com.scu.amazing7action”的 activity 都将會比對成功

  在 intent-filter 節點中,通過 data節點比對外部資料,也就是通過 uri 攜帶外部資料給目标元件。

注意:隻有data的所有的屬性都比對成功時 uri 資料比對才會成功

  為元件定義一個 類别清單,當 intent 中包含這個類别清單的所有項目時才會比對成功。

  ①加載所有的intent filter清單 

②去掉action比對失敗的intent filter 

③去掉url比對失敗的intent filter 

④去掉category比對失敗的intent filter 

⑤判斷剩下的intent filter數目是否為0。如果為0查找失敗傳回異常;如果大于0,就按優先級排序,傳回最高優先級的intent filter

一般設定activity為非公開的

注意:非公開的activity不能設定intent-filter,以免被其他activity喚醒(如果擁有相同的intent-filter)。

不要指定activity的taskaffinity屬性

不要設定activity的launchmode(保持預設)

  注意activity的intent最好也不要設定為flag_activity_new_task

在匿名内部類中使用this時加上activity類名(類名.this,不一定是目前activity)

設定activity全屏

  在其 oncreate()方法中加入:

版權聲明:請尊重個人勞動成果,轉載注明出處,謝謝!

http://my.csdn.net/amazing7

繼續閱讀