Android四大組件之——Activityjava
移動應用體驗與桌面體驗的不一樣之處在於,用戶與應用的互動並不老是在同一位置開始,而是常常以不肯定的方式開始。例如,若是您從主屏幕打開電子郵件應用,可能會看到電子郵件列表,若是您經過社交媒體應用啓動電子郵件應用,則可能會直接進入電子郵件應用的郵件撰寫界面。android
Activity 類的目的就是促進這種範式的實現。當一個應用調用另外一個應用時,調用方應用會調用另外一個應用中的 Activity,而不是整個應用。經過這種方式,Activity 充當了應用與用戶互動的入口點。bash
Activity 提供窗口供應用在其中繪製界面。此窗口一般會填滿屏幕,但也可能比屏幕小,並浮動在其餘窗口上面。一般,一個 Activity 實現應用中的一個屏幕。ide
當用戶瀏覽、退出和返回應用時,應用中的 Activity 實例會在其生命週期的不一樣狀態間轉換。Activity 類會提供許多回調,這些回調會讓 Activity 知曉某個狀態已經更改:系統正在建立、中止或恢復某個 Activity,或者正在銷燬該 Activity 所在的進程。性能
附上官方的Activity生命週期圖示。ui
須要注意一個點,是前一個Activity的onPause執行完,纔會執行下一個Activity的建立,因此在onPause中不能執行較重操做。this
因爲關於生命週期是一個老生常談的問題了,其餘生命週期在此就再也不作拆分解釋了。google
當發生配置變動(屏幕旋轉或切換到多窗口)和因爲內存不足系統對後臺進程進行回收時,會致使Activity被銷燬。此種狀況發生時,系統會回調被銷燬Activity的onSaveInstanceState(),經過Bunlde存儲狀態信息,以保存銷燬瞬間當前Activity的狀態。spa
當這些被銷燬的Activity獲得重建時,系統會將以前保存着狀態信息的Bundle,經過方法onCreate或則onRestoreInstanceState傳遞給重建的Activity,以使其可以完成狀態的恢復。code
在使用onCreate方法獲取Bundle數據時須要進行null判斷,而onRestoreInstanceState則不須要,且後者調用時機在onStart生命週期以後。
任務是用戶在執行某項工做時與之互動的一系列 Activity 的集合。這些 Activity 按照每一個 Activity 打開的順序排列在一個返回堆棧中。返回堆棧按照「後進先出」的對象結構運做。
也就是說,任務是總體的概念——「外」,回退棧指代內部Activity的堆疊——「內」。
- 進入任務前 在清單文件的activity標籤中,能夠經過taskAffinity來標識本身要進入的任務是哪一個(親和性)。
- 進入任務中 當Activity被開啓,而後在存放於回退棧的過程當中,Activity能夠經過清單文件中設置的啓動模式launchMode,來設置回退棧對它的入棧安排。是直接進入(standard)、棧頂複用(singleTop)、棧內單例(singleTask),仍是獨享一個任務(singleInstance)。
除了清單文件,固然還能夠經過Intent設置參數,來標識Activity與任務的關聯方式:
FLAG_ACTIVITY_NEW_TASK == singleTask
FLAG_ACTIVITY_SINGLE_TOP == singleTop
FLAG_ACTIVITY_CLEAR_TOP,若是要啓動的 Activity 已經在當前任務中運行,則不會啓動該 Activity 的新實例,而是會銷燬位於它之上的全部其餘 Activity,並經過 onNewIntent() 將此 intent 傳送給它的已恢復實例(如今位於堆棧頂部)。FLAG_ACTIVITY_CLEAR_TOP 最常與 FLAG_ACTIVITY_NEW_TASK 結合使用。將這兩個標記結合使用,能夠查找其餘任務中的現有 Activity,並將其置於可以響應 intent 的位置。
咱們知道,經過在清單文件中配置Activity的taskAffinity,能夠修改其親和性(Activity 傾向於屬於哪一個任務)。
taskAffinity 屬性採用字符串值,該值必須不一樣於 <manifest>
元素中聲明的默認軟件包名稱,由於系統使用該名稱來標識應用的默認任務親和性。
親和性可在兩種狀況下發揮做用:
- 當啓動 Activity 的 intent 包含 FLAG_ACTIVITY_NEW_TASK 標記時: 默認狀況下,新 Activity 會啓動到調用 startActivity() 的 Activity 的任務中。它會被推送到調用方 Activity 所在的返回堆棧中。可是,若是傳遞給 startActivity() 的 intent 包含 FLAG_ACTIVITY_NEW_TASK 標記,則系統會尋找其餘任務來容納新 Activity。一般會是一個新任務,但也可能不是。若是已存在與新 Activity 具備相同親和性的現有任務,則會將 Activity 啓動到該任務中。若是不存在,則會啓動一個新任務。
- 當 Activity 的 allowTaskReparenting 屬性設爲 "true" 時: 在這種狀況下,一旦和 Activity 有親和性的任務進入前臺運行,Activity 就可從其啓動的任務轉移到該任務。
默認狀況下,若是用戶離開任務較長時間,系統會清除任務中除根 Activity 之外的全部 Activity。當用戶再次返回到該任務時,只有根 Activity 會恢復。 可是,可經過如下屬性修改這一默認行爲:
- alwaysRetainTaskState 若是在任務的根 Activity 中將該屬性設爲 "true",則不會發生上述默認行爲。即便通過很長一段時間後,任務仍會在其堆棧中保留全部 Activity。
- clearTaskOnLaunch 若是在任務的根 Activity 中將該屬性設爲 "true",那麼只要用戶離開任務再返回,堆棧就會被清除到只剩根 Activity。也就是說,它與 alwaysRetainTaskState 正好相反。用戶始終會返回到任務的初始狀態,即使只是短暫離開任務也是如此。
- finishOnTaskLaunch 該屬性與 clearTaskOnLaunch 相似,但它只會做用於單個 Activity 而非整個任務。它還可致使任何 Activity 消失,包括根 Activity。若是將該屬性設爲 "true",則 Activity 僅在當前會話中歸屬於任務。若是用戶離開任務再返回,則該任務將再也不存在。對於那些您不但願用戶可以返回到 Activity 的狀況,可使用此屬性進行設置。
val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)
or
startActivityForResult(intent,requestCode)
複製代碼
若是是startActivityForResult開啓:
- onActivityResult接收結果
- 被開啓Activity關閉時在必要時候經過setResult(resultCode,intentData)傳回結果
經過在<activity>
標籤下,配置<intent-filter>
過濾器,來標識此Activity能夠支持哪些意圖。
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
複製代碼
Android 10 (API 級別 29) 及更高版本對後臺應用可啓動 Activity 的時間施加限制。這些限制有助於最大限度地減小對用戶形成的中斷,而且可讓用戶更好地控制其屏幕上顯示的內容。
幾乎在全部狀況下,後臺應用都應顯示有時效性的通知,以便向用戶提供緊急信息,而非直接啓動 Activity。
在 Android 10 或更高版本上運行的應用只有在知足如下一項或多項條件時,才能啓動 Activity:
- 應用具備可見窗口,例如前臺 Activity。
- 應用在前臺任務的返回棧中擁有 Activity。
- 應用在 Recents 屏幕上現有任務的返回棧中擁有 Activity。
- 應用的某個 Activity 剛在不久前啓動。
- 應用最近爲某個 Activity 調用了 finish()。這僅適用於在調用 finish() 時,應用在前臺或前臺任務的返回棧中擁有 Activity 的狀況。
- 應用具備受系統約束的服務。此狀況僅適用於如下服務,這些服務可能須要啓動界面:AccessibilityService、AutofillService、CallRedirectionService、HostApduService、InCallService、TileService、VoiceInteractionService 和 VrListenerService。
- 應用中的某個服務受另外一個可見應用約束。請注意,綁定到服務的應用必須保持可見,以便後臺應用成功啓動 Activity。
- 應用收到系統的 PendingIntent 通知。對於服務和廣播接收器的掛起 Intent,應用可在該掛起 Intent 發送幾秒鐘後啓動 Activity。
- 應用收到另外一個可見應用發送的 PendingIntent。
- 應用收到它應該在其中啓動界面的系統廣播。
- 應用經過 CompanionDeviceManager API 與配套硬件設備相關聯。此 API 支持應用啓動 API,以響應用戶在配對設備上執行的操做。
- 應用是在設備全部者模式下運行的設備政策控制器。示例用例包括徹底託管的企業設備,以及數字標識牌和自助服務終端等專用設備。
- 用戶已嚮應用授予 SYSTEM_ALERT_WINDOW 權限(在 Android 10設備上運行的應用沒法得到 SYSTEM_ALERT_WINDOW 權限。這是由於繪製疊加層窗口會使用過多的內存,這對低內存 Android 設備的性能十分有害。若是在搭載 Android 9 或更低版本的設備上運行的應用得到了 SYSTEM_ALERT_WINDOW 權限,則即便設備升級到 Android 10,也會保留此權限。不過,尚不具備此權限的應用在設備升級後便沒法得到此權限了)。