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

鸿蒙小语哥 显示全部楼层 发表于 2024-8-28 11:43:58

一、引言

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

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

2.1 启动框架须知

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

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生命周期及方法的入口。

三、源码分析

3.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&lt;IRemoteObject&gt; remote = Remote();
  4. remote-&gt;SendRequest(static\_cast&lt;uint32\_t&gt;(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&lt;IRemoteObject&gt; 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&lt;void()&gt; attachApplicationFunc =
  6.     std::bind(&amp;AppMgrServiceInner::AttachApplication, appMgrServiceInner\_, pid, iface\_cast&lt;IAppScheduler&gt;(app));
  7. taskHandler\_-&gt;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-&gt;SetApplicationClient(appScheduler);
  5. appRecord-&gt;RegisterAppDeathRecipient();
  6. if (appRecord-&gt;GetState() == ApplicationState::APP\_STATE\_CREATE) {
  7.     LaunchApplication(appRecord);
  8. }
  9. eventInfo.pid = appRecord-&gt;GetPriorityObject()-&gt;GetPid();
  10.  eventInfo.processName = appRecord-&gt;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-&gt;LaunchApplication(\*configuration\_);
  16.  appRecord-&gt;SetState(ApplicationState::APP\_STATE\_READY);
  17.  appRecord-&gt;SetRestartResidentProcCount(restartResidentProcCount);
  18.  ......
  19.  appRecord-&gt;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\_-&gt;GetApplicationClient()
  4. ......
  5. launchData.SetProcessInfo(processInfo);
  6. launchData.SetRecordId(appRecordId\_);
  7. launchData.SetUId(mainUid\_);
  8. launchData.SetUserTestInfo(userTestRecord\_);
  9. launchData.SetAppIndex(appIndex\_);
  10.  appLifeCycleDeal\_-&gt;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\_-&gt;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-&gt;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\_-&gt;SetRuntime(std::move(runtime));
  28.      AbilityLoader::GetInstance().RegisterAbility("Ability", [application = application\_]() {
  29.          return Ability::Create(application-&gt;GetRuntime());
  30.      });
  31.  LoadAllExtensions(jsEngine);
  32.  contextDeal-&gt;initResourceManager(resourceManager);
  33.  contextDeal-&gt;SetApplicationContext(application\_);
  34.  application\_-&gt;AttachBaseContext(contextDeal);
  35.  application\_-&gt;SetAbilityRecordMgr(abilityRecordMgr\_);
  36.  application\_-&gt;SetConfiguration(config);
  37.  contextImpl-&gt;SetConfiguration(application\_-&gt;GetConfiguration());
  38.  applicationImpl\_-&gt;SetRecordId(appLaunchData.GetRecordId());
  39.  applicationImpl\_-&gt;SetApplication(application\_);
  40.  mainThreadState\_ = MainThreadState::READY;
  41.  ......
  42.  applicationImpl\_-&gt;PerformAppReady()
  43.  nwebMgr-&gt;PreStartNWebSpawnProcess();
  44.  ......
  45.  // init resourceManager.
  46.  ......
  47. }

复制代码

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

  1. void ModuleRunningRecord::LaunchPendingAbilities()
  2. {
  3. for (const auto &amp;item : abilities\_) {
  4.     const auto &amp;ability = item.second;
  5.     if (ability-&gt;GetState() == AbilityState::ABILITY\_STATE\_CREATE &amp;&amp; ability-&gt;GetToken() &amp;&amp;
  6.         appLifeCycleDeal\_-&gt;GetApplicationClient()) {
  7.         appLifeCycleDeal\_-&gt;LaunchAbility(ability);
  8.         ability-&gt;SetState(AbilityState::ABILITY\_STATE\_READY);
  9.     }
  10.  }
  11. }
  12. void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
  13. {
  14.  appLifeCycleDeal\_-&gt;LaunchAbility(ability);
  15.  ability-&gt;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\_ &amp;&amp; ability) {
  4.     appThread\_-&gt;ScheduleLaunchAbility(\*(ability-&gt;GetAbilityInfo()), ability-&gt;GetToken(),
  5.         ability-&gt;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_ptrAAFwk::Want &want)
  2. {
  3. auto task = [weak, abilityRecord]() {
  4.     ...
  5.     auto appThread = weak.promote();
  6.     appThread-&gt;HandleLaunchAbility(abilityRecord);
  7. };
  8. mainHandler\_-&gt;PostTask(task);
  9. }
  10. MainThread::HandleLaunchAbility(const std::shared_ptr<AbilityLocalRecord> &abilityRecord)
  11. {
  12.  abilityRecordMgr\_-&gt;SetToken(abilityToken);
  13.  abilityRecordMgr\_-&gt;AddAbilityRecord(abilityToken, abilityRecord);
  14.  //创建AbilityStage
  15.  std::shared\_ptr&lt;AbilityRuntime::Context&gt; stageContext = application\_-&gt;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&lt;AbilityRuntime::ContextImpl&gt;();
  5. stageContext-&gt;SetParentContext(abilityRuntimeContext\_);
  6. stageContext-&gt;InitHapModuleInfo(hapModuleInfo);
  7. stageContext-&gt;SetConfiguration(GetConfiguration());
  8. auto abilityStage = AbilityRuntime::AbilityStage::Create(runtime\_, \*moduleInfo);
  9. abilityStage-&gt;Init(stageContext);
  10.  Want want;
  11.  abilityStage-&gt;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&lt;Runtime&gt;&amp; runtime, const AppExecFwk::HapModuleInfo&amp; hapModuleInfo)
  3. {
  4. ......
  5. switch (runtime-&gt;GetLanguage()) {
  6.     case Runtime::Language::JS:
  7.         return JsAbilityStage::Create(runtime, hapModuleInfo);
  8.     default:
  9.         return std::make\_shared&lt;AbilityStage&gt;();
  10.  }
  11. }
  12. void AbilityStage::AddAbility(const sptr<IRemoteObject> &token,
  13.  const std::shared\_ptr&lt;AppExecFwk::AbilityLocalRecord&gt; &amp;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&amp; jsRuntime = static\_cast&lt;JsRuntime&amp;&gt;(\*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&lt;JsAbilityStage&gt;(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&amp; nativeEngine = jsRuntime\_.GetNativeEngine();
  24.  NativeValue\* value = jsAbilityStageObj\_-&gt;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和源码路径也都列举了出来,有疑问可自行获取源码加深理解。

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

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

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

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

返回顶部