[经验分享] 跟着源码学习OpenHarmony应用启动流程-Application&Ability初始化

诚迈-陆志刚 显示全部楼层 发表于 2024-7-15 16:09:11
跟着源码学习OpenHarmony应用启动流程-Application&Ability初始化

(文章已获得诚迈科技资深研发工程师-汪语授权)


一、引言


本文基于OpenAtom OpenHarmony(以下简称“OpenHarmony”) v4.0 Release版本的源码,对应用进程初始化后MainThread初始化及调用AttachApplication、LaunchApplication、LaunchAbility的过程做了分析和总结,该流程贯穿了应用程序的用户进程和系统服务进程。



二、启动框架与核心类简介

2.1 启动框架须知
如下图所示,OpenHarmony应用冷启动过程大致分为四个阶段:应用进程创建&初始化、Application&Ability初始化、Ability/AbilityStage生命周期、加载绘制首页。


1.png


2.2 应用启动流程的核心类须知
●AppMgrService是应用管理服务主线程类,实现了IPC调用IAppMgr的接口,并通过AMSEventHandler将进程内各类事件及任务发送到主线程。
●AppRunningManager记录了应用的信息、应用的运行状态、进程信息等,内部持有了模块运行信息列表,应用第一次启动时,会先创建。
●AppSpawn是app孵化器,通过监听本地socket,接收客户端的请求消息。创建Ability应用所在进程,为Ability应用设置相应的权限,并预加载一些通用的模块。
●AbilityLoader负责注册和加载开发者Ability模块。开发者开发的Ability先调用AbilityLoader的注册接口注册到框架中,接着Ability启动时会被实例化。
●AbilityManager负责AbilityKit和Ability管理服务进行IPC的通信。
●MainThread是应用进程的核心类。应用进程内各类事件及任务通过MainThread中mainHandler投递到主线程并调用MainThread中的方法执行。
●AbilityThread是应用线程的核心类,是操作各种Ability生命周期及方法的入口。



三、源码分析

1.主线程初始化,通过IPC机制,AMS调用AttachApplication,再回调AMS端
foundation\ability\ability_runtime\frameworks\native\appkit\app\main_thread.cpp

  1. void MainThread::Start()
  2. {
  3.      sptr<MainThread> thread = sptr<MainThread>(new (std::nothrow) MainThread());
  4.      ......
  5.      thread->Init(runner);
  6.      thread->Attach();  }

  7. void MainThread::Init()
  8. {
  9.     auto task = [weak]() {
  10.         auto appThread = weak.promote();
  11.         appThread->SetRunnerStarted(true);
  12.     };
  13.     if (!mainHandler_->PostTask(task)) {
  14.         HILOG_ERROR("MainThread::Init PostTask task failed");
  15.     }
  16.     watchdog_->Init(mainHandler_);
  17.     extensionConfigMgr_->Init();
  18. }

  19. void MainThread::Attach()
  20. {
  21.     if (!ConnectToAppMgr()) {
  22.         return;
  23.     }
  24.     mainThreadState_ = MainThreadState::ATTACH;
  25. }

  26. bool MainThread::ConnectToAppMgr()
  27. {
  28.     auto object = OHOS::DelayedSingleton<SysMrgClient>::GetInstance()->GetSystemAbility(APP_MGR_SERVICE_ID);
  29.     appMgr_ = iface_cast<IAppMgr>(object);
  30.     appMgr_->AttachApplication(this);  
  31. }
复制代码

客户端发送 attach application 请求
foundation\ability\ability_runtime\interfaces\inner_api\app_manager\src\appmgr\app_mgr_proxy.cpp


  1. AppMgrProxy::AttachApplication(const sptr<IRemoteObject> &obj)
  2. {
  3.     sptr<IRemoteObject> remote = Remote();
  4.     remote->SendRequest(static_cast<uint32_t>(IAppMgr::Message::APP_ATTACH_APPLICATION), ...);
  5. }
复制代码

服务端收到 attach application 请求
foundation\ability\ability_runtime\interfaces\inner_api\app_manager\src\appmgr\app_mgr_stub.cpp


  1. int32_t AppMgrStub::HandleAttachApplication(MessageParcel &data, MessageParcel &reply)
  2. {
  3.     sptr<IRemoteObject> client = data.ReadRemoteObject();
  4.     AttachApplication(client);  
  5. }
复制代码


foundation\ability\ability_runtime\services\appmgr\src\app_mgr_service.cpp




  1. void AppMgrService::AttachApplication(const sptr<IRemoteObject> &app)
  2. {
  3.    pid_t pid = IPCSkeleton::GetCallingPid();
  4.     AddAppDeathRecipient(pid);
  5.     std::function<void()> attachApplicationFunc =
  6.         std::bind(&AppMgrServiceInner::AttachApplication, appMgrServiceInner_, pid, iface_cast<IAppScheduler>(app));
  7.     taskHandler_->SubmitTask(attachApplicationFunc, TASK_ATTACH_APPLICATION);
  8. }
复制代码

函数处理逻辑回到服务层
foundation\ability\ability_runtime\services\appmgr\src/app_mgr_service_inner.cpp


  1. void AppMgrServiceInner::AttachApplication(const pid_t pid, const sptr<IAppScheduler> &appScheduler)
  2. {
  3.     ......
  4.     appRecord->SetApplicationClient(appScheduler);
  5.     appRecord->RegisterAppDeathRecipient();
  6.     if (appRecord->GetState() == ApplicationState::APP_STATE_CREATE) {
  7.         LaunchApplication(appRecord);
  8.     }
  9.     eventInfo.pid = appRecord->GetPriorityObject()->GetPid();
  10.     eventInfo.processName = appRecord->GetProcessName();
  11.     AAFwk::EventReport::SendAppEvent(AAFwk::EventName::APP_ATTACH, HiSysEventType::BEHAVIOR, eventInfo);
  12. }<div class="document"><div class="section"><p class="paragraph text-align-type-left" style="margin: 3pt 0pt; font-family: 等线; font-size: 12pt;"><span data-font-family="default" style="font-size: 11pt; letter-spacing: 0pt; vertical-align: baseline;">
  13. </span></p></div></div>void AppMgrServiceInner::LaunchApplication(const std::shared_ptr<AppRunningRecord> &appRecord)
  14. {
  15.     appRecord->LaunchApplication(*configuration_);
  16.     appRecord->SetState(ApplicationState::APP_STATE_READY);
  17.     appRecord->SetRestartResidentProcCount(restartResidentProcCount);
  18.     ......
  19.     appRecord->LaunchPendingAbilities();
  20.     AAFwk::EventReport::SendAppEvent(AAFwk::EventName::APP_LAUNCH, HiSysEventType::BEHAVIOR, eventInfo);
  21. }
复制代码
2.应用初始化,通过AppRunningRecord调用LaunchApplication
应用第一次启动时,会先创建AppRunningRecord
foundation\ability\ability_runtime\services\appmgr\src\app_running_record.cpp
  1. void AppRunningRecord::LaunchApplication(const Configuration &config)
  2. {
  3.     appLifeCycleDeal_->GetApplicationClient()
  4.     ......
  5.     launchData.SetProcessInfo(processInfo);
  6.     launchData.SetRecordId(appRecordId_);
  7.     launchData.SetUId(mainUid_);
  8.     launchData.SetUserTestInfo(userTestRecord_);
  9.     launchData.SetAppIndex(appIndex_);
  10.     appLifeCycleDeal_->LaunchApplication(launchData, config);
  11. }
复制代码

foundation\ability\ability_runtime\services\appmgr\src\app_lifecycle_deal.cpp


  1. void AppLifeCycleDeal::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
  2. {
  3.     appThread_->ScheduleLaunchApplication(launchData, config);
  4. }
复制代码

处理启动应用(加载依赖库、初始化资源管理器等)等逻辑
foundation\ability\ability_runtime\frameworks\native\appkit\app\main_thread.cpp


  1. void MainThread::ScheduleLaunchApplication(const AppLaunchData &data, const Configuration &config)
  2. {
  3.     appThread->HandleLaunchApplication(data, config);
  4. }

  5. void MainThread::HandleLaunchApplication(const AppLaunchData &data, const Configuration &config)
  6. {
  7.     if (!InitCreate(contextDeal, appInfo, processInfo)) {
  8.         return;
  9.     }
  10.     if (IsNeedLoadLibrary(bundleName)) {
  11.         ChangeToLocalPath(bundleName, appInfo.moduleSourceDirs, localPaths);
  12.         LoadAbilityLibrary(localPaths);
  13.         LoadNativeLiabrary(bundleInfo, appInfo.nativeLibraryPath);
  14.     }
  15.     if (appInfo.needAppDetail) {
  16.         LoadAppDetailAbilityLibrary(appInfo.appDetailAbilityLibraryPath);
  17.     }
  18.     LoadAppLibrary();
  19.     if (isStageBased) {
  20.         AppRecovery::GetInstance().InitApplicationInfo(GetMainHandler(), GetApplicationInfo());
  21.     }
  22.     // create contextImpl
  23.     ......
  24.     if (isStageBased) {
  25.         // Create runtime
  26.         ......
  27.         application_->SetRuntime(std::move(runtime));
  28.         AbilityLoader::GetInstance().RegisterAbility("Ability", [application = application_]() {
  29.             return Ability::Create(application->GetRuntime());
  30.         });
  31.     LoadAllExtensions(jsEngine);
  32.     contextDeal->initResourceManager(resourceManager);
  33.     contextDeal->SetApplicationContext(application_);
  34.     application_->AttachBaseContext(contextDeal);
  35.     application_->SetAbilityRecordMgr(abilityRecordMgr_);
  36.     application_->SetConfiguration(config);
  37.     contextImpl->SetConfiguration(application_->GetConfiguration());

  38.     applicationImpl_->SetRecordId(appLaunchData.GetRecordId());
  39.     applicationImpl_->SetApplication(application_);
  40.     mainThreadState_ = MainThreadState::READY;
  41.     ......
  42.     applicationImpl_->PerformAppReady()
  43.     nwebMgr->PreStartNWebSpawnProcess();
  44.     ......
  45.     // init resourceManager.
  46.     ......
  47. }
复制代码

3. 通过RunningRecord调用LaunchPendingAbilities,最终创建Ability
foundation\ability\ability_runtime\services\appmgr\src/module_running_record.cpp


  1. void ModuleRunningRecord::LaunchPendingAbilities()
  2. {
  3.     for (const auto &item : abilities_) {
  4.         const auto &ability = item.second;
  5.         if (ability->GetState() == AbilityState::ABILITY_STATE_CREATE && ability->GetToken() &&
  6.             appLifeCycleDeal_->GetApplicationClient()) {
  7.             appLifeCycleDeal_->LaunchAbility(ability);
  8.             ability->SetState(AbilityState::ABILITY_STATE_READY);
  9.         }
  10.     }
  11. }
  12. void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
  13. {
  14.     appLifeCycleDeal_->LaunchAbility(ability);
  15.     ability->SetState(AbilityState::ABILITY_STATE_READY);
  16. }
复制代码

通过IPC调用ScheduleLaunchAbility函数
foundation\ability\ability_runtime\services\appmgr\src/app_lifecycle_deal.cpp


  1. AppLifeCycleDeal::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
  2. {
  3.     if (appThread_ && ability) {
  4.         appThread_->ScheduleLaunchAbility(*(ability->GetAbilityInfo()), ability->GetToken(),
  5.             ability->GetWant());
  6.     }
  7. }
复制代码

foundation\ability\ability_runtime\frameworks\native\appkit\app\main_thread.cpp


  1. MainThread::ScheduleLaunchAbility(const AbilityInfo &info, const sptr<IRemoteObject> &token, const std::shared_ptr<AAFwk::Want> &want)
  2. {
  3.     auto task = [weak, abilityRecord]() {
  4.         ...
  5.         auto appThread = weak.promote();
  6.         appThread->HandleLaunchAbility(abilityRecord);
  7.     };
  8.     mainHandler_->PostTask(task);
  9. }
  10. MainThread::HandleLaunchAbility(const std::shared_ptr<AbilityLocalRecord> &abilityRecord)
  11. {
  12.     abilityRecordMgr_->SetToken(abilityToken);
  13.     abilityRecordMgr_->AddAbilityRecord(abilityToken, abilityRecord);
  14.     //创建AbilityStage
  15.     std::shared_ptr<AbilityRuntime::Context> stageContext = application_->AddAbilityStage(abilityRecord);
  16.     //启动Ability线程
  17.     AbilityThread::AbilityThreadMain(application_, abilityRecord, stageContext);  
  18. }
复制代码

foundation\ability\ability_runtime\frameworks\native\appkit\app\ohos_application.cpp


  1. bool OHOSApplication::AddAbilityStage(const AppExecFwk::HapModuleInfo &hapModuleInfo)
  2. {
  3.      ......
  4.     auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
  5.     stageContext->SetParentContext(abilityRuntimeContext_);
  6.     stageContext->InitHapModuleInfo(hapModuleInfo);
  7.     stageContext->SetConfiguration(GetConfiguration());
  8.     auto abilityStage = AbilityRuntime::AbilityStage::Create(runtime_, *moduleInfo);
  9.     abilityStage->Init(stageContext);
  10.     Want want;
  11.     abilityStage->OnCreate(want);
  12.     abilityStages_[hapModuleInfo.moduleName] = abilityStage;
  13.     return true;
  14. }
复制代码


foundation\ability\ability_runtime\frameworks\native\appkit\ability_runtime\app\ability_stage.cpp




  1. std::shared_ptr<AbilityStage> AbilityStage::Create(
  2.     const std::unique_ptr<Runtime>& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo)
  3. {
  4.     ......
  5.     switch (runtime->GetLanguage()) {
  6.         case Runtime::Language::JS:
  7.             return JsAbilityStage::Create(runtime, hapModuleInfo);
  8.         default:
  9.             return std::make_shared<AbilityStage>();
  10.     }
  11. }

  12. void AbilityStage::AddAbility(const sptr<IRemoteObject> &token,
  13.     const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &abilityRecord)
  14. {
  15.     ......
  16.     abilityRecords_[token] = abilityRecord;
  17. }
复制代码
foundation\ability\ability_runtime\frameworks\native\appkit\ability_runtime\app\ability_stage.cpp
  1. td::shared_ptr<AbilityStage> JsAbilityStage::Create(){
  2.     auto& jsRuntime = static_cast<JsRuntime&>(*runtime);
  3.     std::string srcPath(hapModuleInfo.name);
  4.     std::string moduleName(hapModuleInfo.moduleName);
  5.     moduleName.append("::").append("AbilityStage");
  6.     ......
  7.     //srcPath.append("/assets/js/");
  8.     //srcPath.append("AbilityStage.abc");
  9.     srcPath.append(hapModuleInfo.srcPath);
  10.     srcPath.append("/AbilityStage.abc");
  11.     auto moduleObj = jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath,
  12.         hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, commonChunkFlag);
  13.     return std::make_shared<JsAbilityStage>(jsRuntime, std::move(moduleObj));
  14. }

  15. void JsAbilityStage::Init(const std::shared_ptr<Context> &context)
  16. {
  17.     AbilityStage::Init(context);
  18. }

  19. void JsAbilityStage::OnCreate(const AAFwk::Want &want) const
  20. {
  21.     AbilityStage::OnCreate(want);
  22.     ......
  23.     auto& nativeEngine = jsRuntime_.GetNativeEngine();
  24.     NativeValue* value = jsAbilityStageObj_->Get();
  25.     nativeEngine.CallFunction(value, methodOnCreate, nullptr, 0);
  26. }
  27. //AbilityStage
  28. void AbilityStage::Init(const std::shared_ptr<Context>& context){
  29.     context_ = context;
  30. }
  31. void AbilityStage::OnCreate(const AAFwk::Want &want) cons{
  32.     HILOG_DEBUG("AbilityStage OnCreate come.");
  33. }
复制代码

foundation\ability\ability_runtime\frameworks\native\ability\native\ability_thread.cpp



至此,关于应用启动过程中application和ability初始化梳理清楚,OpenHarmony的源码关键Api和源码路径也都列举了出来,有疑问可自行获取源码加深理解。


四、总结-时序图
本文基于以上源码分析进行了总结,绘制了时序图,如下图所示。

22.png


五、参考链接
OpenHarmony 4.0 Release官方文档:
https://gitee.com/openharmony/do ... lease.mdOpenHarmony 应用模型介绍:https://gitee.com/openharmony/do ... lity-launch-type.md
OpenHarmony IPC / RPC通信开发指导:
https://gitee.com/openharmony/communication_ipc
OpenHarmony源码仓获取地址:
https://www.openharmony.cn/download
Ability启动过程:
https://ost.51cto.com/posts/22188


无用

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部