Ⅰ android activity 按back鍵 執行什麼過程
進程只是一個APP的容器,容器內的內容不會因為容器的空置而消失。但一旦容器被銷毀,容器中的內容也會隨之銷毀。當用戶按下back鍵時,實際上是執行了一個棧操作,具體來說就是棧頂元素被移除(即彈出,英文稱為pop操作)。這一過程會觸發棧頂Activity的onBackPressed()方法,默認情況下,這個方法會調用finish(),finish()方法則會進一步調用Activity的onDestroy()方法,從而銷毀當前Activity。
而當用戶按下home鍵時,系統的處理方式則是將整個任務棧掛起並放到後台,使用戶回到啟動器首頁。此時,Activity並未被銷毀,因此不會觸發Activity的onDestroy()方法。至於長按home鍵啟動任務管理器來結束應用,這種情況下,進程的存在與否則取決於具體的手機型號。一些手機可能會銷毀應用(即銷毀Application類的實例),但進程作為容器仍然存在,只是其中的內容為空。如果發現進程消失,通常是因為系統回收了空進程。而在另一些手機上,直接結束進程的操作可能會導致整個進程被徹底銷毀。
綜上所述,按下back鍵和home鍵的不同處理方式,導致了兩種不同的結果:一種是銷毀當前Activity並調用其生命周期方法;另一種則是簡單地掛起任務棧並將其移至後台,僅在用戶再次啟動應用時才會重新載入。
需要注意的是,進程的空置並不意味著其完全消失,這與進程的生命周期管理緊密相關。在某些情況下,即使應用未運行,其對應的進程也可能仍然存在於後台,等待下次需要時被重新激活。
Ⅱ Intent#FLAG_ACTIVITY_CLEAR_TOP 真的會 clear top 嗎
前幾天,處理了一個App內草稿丟失的用戶反饋。許多用戶反映在連續保存多個草稿後,草稿箱中只有一個草稿,這顯然是發生了草稿丟失的情況。通過分析用戶反饋的數據,發現他們的系統版本都在Android 7.0以下。
經過一段時間的調查,最終發現是草稿被覆蓋了,原因是在保存草稿後,錄制頁、編輯頁、發布頁等鏈路頁面沒有被關閉,再次進入錄制環節時錄制頁復用了狀態,導致保存草稿時發生了草稿替換。那麼,問題就來了,為什麼會發生這樣的情況呢?這需要從保存草稿那一刻說起。
在發現問題時,我們注意到,在正常情況下,保存草稿後會關閉錄制鏈路上的活動,這通常通過Intent#FLAG_ACTIVITY_CLEAR_TOP | Intent#FLAG_ACTIVITY_NEW_TASK來實現。從代碼邏輯來看,這包括在Intent中添加clear_top標志,並設置跳轉到首頁。這里的返回的是MainActivity,從表面上看沒有問題。
然而,在嘗試在小米10 Pro上進行測試時,保存草稿後沒有出現復現問題的情況。回到首頁並按下返回鍵後,直接退出了App。這表明錄制鏈路頁面被關閉了。在更換多台手機後,終於在一台Android 5.1設備上成功復現了這種情況,發現保存草稿並返回首頁時,再次按下返回鍵會回到發布頁,錄制鏈路依然存在。
核心問題在於:為什麼在Android 5.1設備上clear_top這個標志沒有生效?
關於Intent#FLAG_ACTIVITY_CLEAR_TOP,其主要功能是:在目標活動已經存在時,將目標活動所在的任務移動到前台,然後結束目標活動上層的所有活動,並最終打開目標活動。不過,Intent#FLAG_ACTIVITY_CLEAR_TOP如何判斷目標活動已經存在這一點,在注釋中並未詳細說明。
回到我們的工程中。一般情況下,首頁、錄制頁、編輯頁、發布頁處於同一個任務堆棧中,通過adb列印的活動堆棧信息也可以確認這一點。
adb shell mpsys activity activities | grep 'com.liaoapp.musically'
通過查看這幾個活動的啟動模式,並沒有發現任何不同之處:VideoRecordNewActivity: singleTask VideoPublishEditActivity: standard(default) VideoPublishActivity: singleTask
這里我們大膽猜測,不同版本的ROM對Intent#FLAG_ACTIVITY_CLEAR_TOP的處理可能有差異,導致這個標志沒有生效。
為了驗證這個假設,我們創建了一個Demo工程,構建了A、B、C三個空頁面,分別對應首頁、錄制頁、發布頁,跳轉路徑為:A -> B -> C -> A。其中A、B、C的啟動模式分別為singleTop, singleTask, singleTask,與App內的錄制鏈路一致。
在測試中,我們發現C使用clear_top回到A後,並沒有將B和C關閉掉。這讓我們懷疑是否是App內部對Activity或Intent的處理方式有誤。進一步分析發現,在Android 5.1測試機上運行時,保存草稿後任務棧並沒有被清理,這讓我們懷疑是否是ROM的問題。在模擬器上運行測試,也出現了同樣的情況,這讓我們開始懷疑是否是Android的Bug。
在對代碼進行深入分析後,我們發現是由於SplashActivity作為啟動Activity,被聲明為activity-alias,其targetActivity指向了MainActivity。在AndroidManifest中查看SplashActivity和MainActivity的聲明時,我們發現SplashActivity被聲明為了activity-alias,其targetActivity指向了MainActivity。
為了解決這個問題,我們修改了Demo工程,添加了Splash頁面,並將其聲明為activity-alias。現在Demo的啟動流程變成了:Splash -> A -> B -> C -> A。在修改後再次進行測試,結果在Android 5.1測試機上確實復現了問題,即C使用clear_top打開A後,並沒有將B和C關閉掉。這進一步驗證了是由於activity-alias的存在導致了clear_top標志沒有生效。
最終,我們發現是由於活動啟動流程中對Intent#FLAG_ACTIVITY_CLEAR_TOP標志的處理存在差異,導致在Android 5.1設備上該標志沒有生效。通過對活動記錄、任務記錄和任務棧的深入分析,我們發現Android 6.0及以下版本和Android 7.0及以上版本在處理clear_top標志時存在差異。Android 7.0及以上版本在啟動流程中對ActivityRecord#realActivity進行了調整,使得在啟動活動時,如果目標活動是某個activity-alias的targetActivity,那麼在處理clear_top標志時能夠正確地結束目標活動上層的所有活動。
通過這個分析,我們了解到Intent#FLAG_ACTIVITY_CLEAR_TOP確實會清空頂部活動,但在不同的Android版本中,其行為可能會有所不同。解決這個問題的關鍵在於確保在啟動鏈路中正確處理activity-alias和明確指定目標活動的targetActivity,以確保在需要時clear_top標志能夠生效。
Ⅲ Activity的幾種啟動模式
一.先理解棧的概念(放置Activity實例的容器)
1.Task(線性表)
任務棧Task,用來放置Activity實例的容器,先進後出,主要有2個基本操作:壓棧和出棧,其所存放的Activity是不支持重新排序的, 只能根據壓棧和出棧操作更改Activity的順序 。
2.app啟動時,系統會為它默認創建一個對應的Task,用來放置根Activity
ps: Activity之間可以相互啟動,當前應用的Activity可以去啟動其他應用的Activity(相機),那麼就是說棧的功能可以把其它app的activity加入到自己app的棧里.
所以Task可以理解為負責管理所有用到的Activity實例的棧,但是.android5.0之後 跨進程調用activity,這個activity會被放入到一個新的棧中。
二.啟動模式(只能根據壓棧和出棧操作更改Activity的順序,所以是啟動模式是以哪種姿勢入棧)
通過在AndroidManifest文件中的屬性andorid:launchMode來設置或者通過Intent的flag來設置
1.standard(常規姿勢入棧)
默認模式。在這個模式下,都會默認創建一個新的實例。因此,在這種模式下,可以有多個相同的實例,也允許多個相同Activity疊加。應用場景:絕大多數Activity。
2.singleTop(棧頂復用姿勢入棧)==FLAG_ACTIVITY_SINGLE_TOP
棧頂復用模式,如果要開啟的activity在任務棧的頂部已經存在,就不會創建新的實例,而是調用 onNewIntent() 方法。避免棧頂的activity被重復的創建。應用場景:在通知欄點擊收到的通知,然後需要啟動一個Activity,這個Activity就可以用singleTop,否則每次點擊都會新建一個Activity。某個場景下連續快速點擊,啟動了兩個Activity。如果這個時候待啟動的Activity使用 singleTop模式也是可以避免這個Bug的。
3.singleTask(棧內復用姿勢入棧)==FLAG_ACTIVITY_CLEAR_TOP
棧內復用模式, activity只會在任務棧裡面存在一個實例。如果要激活的activity,在任務棧裡面已經存在,就不會創建新的activity,而是復用這個已經存在的activity,調用 onNewIntent() 方法,並且清空這個activity任務棧上面所有的activity( CLEAR_TOP回到棧頂 )。應用場景:大多數App的主頁。對於大部分應用,當我們在主界面點擊回退按鈕的時候都是退出應用,那麼當我們第一次進入主界面之後,主界面位於棧底,以後不管我們打開了多少個Activity,只要我們再次回到主界面,都應該使用將主界面Activity上所有的Activity移除的方式來讓主界面Activity處於棧頂,而不是往棧頂新加一個主界面Activity的實例,通過這種方式能夠保證退出應用時所有的Activity都能報銷毀。
4.singleInstance(不入棧)
單一實例模式,整個手機操作系統裡面只有一個實例存在。不同的應用去打開這個activity 共享公用的同一個activity。他會運行在自己單獨,獨立的任務棧裡面,並且任務棧裡面只有他一個實例存在。應用場景:呼叫來電界面。這種模式的使用情況比較罕見,在Launcher中可能使用。或者你確定你需要使Activity只有一個實例。建議謹慎使用。
5.FLAG_ACTIVITY_NO_HISTORY
Activity使用這種模式啟動Activity,當該Activity啟動其他Activity後,該Activity就消失了,不會保留在Activity棧中。
1.getTaskId();獲取當前activity所處的棧
2.同一個應用程序中的activity的親和性一樣(taskAffinity),也就是說 Actviitya intent時setFalg(Intent.FLAG_ACTIVITY_NEW_TASK)到Activityb 但是Actviitya和Activityb 還是一個棧
在不同的應用中跳轉才會創建新的Task。
3.在Activity上下文之外啟動Activity需要給Intent設置FLAG_ACTIVITY_NEW_TASK標志,不然會報異常。
四 FLAG_ACTIVITY_CLEAR_TASK(必須和FLAG_ACTIVITY_NEW_TASK一起使用)
清空棧內activity,只留下這個activity
Ⅳ ActivityManager是什麼如何高效使用
ActivityManager是Android系統中的一個核心服務,負責管理應用程序的生命周期和任務堆棧,確保應用程序在後台運行時不會佔用過多資源,同時為用戶提供流暢的操作體驗。以下是關於ActivityManager的詳細介紹以及如何高效使用它的方法:
一、ActivityManager的主要功能
二、如何高效使用ActivityManager
合理使用Activity生命周期方法
優化任務堆棧
管理內存
利用ActivityManager提供的API
綜上所述,高效使用ActivityManager需要開發者深入理解其功能和API,並結合實際應用場景進行合理的優化和管理。