一篇帶你了解Ability啟動過程
Ability是應用所具備能力的抽象,也是應用程序的重要組成部分。一個應用可以具備多種能力(即可以包含多個Ability),OpenHarmony OS支持應用以Ability為單位進行部署。Ability可以分為FA(Feature Ability)和PA(Particle Ability)兩種類型,每種類型為開發者提供了不同的模板,以便實現不同的業務功能。
以上摘自官方文檔,本文簡要介紹Page應用(AceAbility為例)啟動過程 ,減少入手難度。
1、AppSpawn進程響應應用start請求
啟動應用命令:
2、fork子進程(aka.應用)
AppSpawnChild中執行應用啟動前步驟,如清理環境、權限鑒權等后,調用content->runChildProcessor(content, client)。
3、應用主線程Start
在Start()中裝備應用MainThread的EventRunner和MainHandler,在EventRunner::Run等待event分發處理和event循環,這里是應用的主線程,也負責拉起其他的線程。這里有必要簡要說明OHOS的事件通知機制。
ohos基礎框架中的notification機制
代碼路徑:
OHOS event-notification機制可以保證一個線程中可以安全地向其他線程投遞任務,只要拿到其他線程的Handler或者EventRunner即可。
UML類圖:
說明:
(1). EventHandler負責投遞封裝好的event到EventRunner的EventQueue中,并提供ProcessEvent接口供子類重寫業務邏輯。
(2). EventRunner負責線程運行的抽象,實際線程運行委托給EventInnerRunner實現。
(3). EventInnerRunner/EventRunnerImpl類是線程運行具體實現,提供ThreadMain()作為std::thread運行入口,在Run()完成event分發處理和event循環(EventHanlder在投遞event時候,將handler本身封裝在event中,之所以這樣做,可能是為了同時支持callback型task和EventHandler中重寫ProcessEvent處理方式)。
4、MainThread::Init初始化
拉起看DFX的看門狗線程和信號處理線程,設置應用主線程狀態。
5、向AMS注冊應用,并調度運行
應用調用Attach(),需要向AMS注冊表項資源。
MainThread是IRemoteStub<IAppScheduler>子類,向AMS注冊反向死亡通知,應用退出能及時釋放AMS相關資源。
獲取AppMgr Proxy對象 AttachApplication之后,AMS調度Application狀態。
說明:
MainThread、AMS、ABMS運行在不同進程中,其中AMS、ABMS是SA,使用ohos IPC機制通信。
1.MainThread 是IRemoteStub<IAppScheduler> 子類,是一個匿名IPC對象(匿名這里指的是沒有注冊到samgr,無said),反向死亡通知到AMS,應用結束時候可以通知AMS回收已分配的AppRunningRecord資源。
2.AppThread(應用主線程,即MainThread)向AMS發送APP_ATTACH_APPLICATION請求并置MainThread狀態為Attach,AMS側收到請求創建appRecord,標記APP_STATE_CREATE。
3.AMS判斷appRecord 為ApplicationState::APP_STATE_CREATE,向Application發送SCHEDULE_LAUNCH_APPLICATION_TRANSACTION請求。
4.AMS標記appRecord狀態為APP_STATE_READY。
5.AppThread接收到AMS的SCHEDULE_LAUNCH_APPLICATION_TRANSACTION請求后,調用ScheduleLaunchApplication向MainThread投遞任務。
該task被執行時調用MainThread::HandleLaunchApplication,調用LoadAbilityLibrary(如加載libace.z.so等庫保存句柄)、LoadNativeLiabrary、LoadAppLibrary、設置Application上下文信息、從BundleMgr獲取Bundle信息、初始化資源管理器InitResourceManager。(此處有區分應用模型,一般是FA模型或者Stage,不做詳細介紹,有興趣自己研究)。
6.AppThread收到AMS的SCHEDULE_LAUNCH_ABILITY_TRANSACTION請求,調用HandleLaunchAbility()->AbilityThread::AbilityThreadMain(),創建AbilityThread,調用AbilityThread::Attach(),依據AbilityType創建相應的Ability(這里以AceAbility為例),初始化Ability 。
Ability 初始化這里有幾處值得注意。
(1)、Ability有若干類型如: AceAbility、AceFormAbility、AceServiceAbility、AceDataAbility等,代碼中有相關類。
(2)、創建AbilityThread的AbilityHandler時候,將MainEventRunner 作為參數傳入,因此AbilityThread用的還是MainEventRunner事件循環。
(3)、在這里創建AbilityWindow(初始化等到Ability的OnStart)、注冊監聽(AbilityWindow和圖形相關,比較重要)。
備注:AMS在AppMgrServiceInner::LaunchApplication中會調用appRecord->LaunchPendingAbilities(),調度應用Ability,感興趣可以自行研究。
7.調用AttachAbilityThread ,want:PARAM_RESV_CALL_TO_FOREGROUND,將Ability調度到前端。
8.ABMS發送ATTACH_ABILITY_THREAD請求到AMS。
9.AMS調用AppThread->ScheduleForegroundApplication()。
10.App線程調用ScheduleForegroundApplication主要是設置App狀態,并發送APP_APPLICATION_FOREGROUNDED通知AMS。
11.AMS收到請求,標記相應AppRecord狀態為ApplicationState::APP_STATE_FOREGROUND,應用和AMS進程狀態同步。
備注:后續AMS觸發ABMS調用ScheduleAbilityTransaction調用PageAbilityImpl::HandleAbilityTransaction()->AceAbility::OnStart()、Ability::OnStart() InitWindow初始化窗口、加載Dom控件樹、圖形渲染等。