OpenHarmony开发者论坛
标题: 跟着源码学习OpenHarmony应用启动流程-Application&Ability初始化 [打印本页]
作者: 诚迈-陆志刚 时间: 2024-7-15 16:09
标题: 跟着源码学习OpenHarmony应用启动流程-Application&Ability初始化
跟着源码学习OpenHarmony应用启动流程-Application&Ability初始化
(文章已获得诚迈科技资深研发工程师-汪语授权)
一、引言
本文基于OpenAtom OpenHarmony(以下简称“OpenHarmony”) v4.0 Release版本的源码,对应用进程初始化后MainThread初始化及调用AttachApplication、LaunchApplication、LaunchAbility的过程做了分析和总结,该流程贯穿了应用程序的用户进程和系统服务进程。
二、启动框架与核心类简介
2.1 启动框架须知
如下图所示,OpenHarmony应用冷启动过程大致分为四个阶段:应用进程创建&初始化、Application&Ability初始化、Ability/AbilityStage生命周期、加载绘制首页。
(, 下载次数: 1)
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
- void MainThread::Start()
- {
- sptr<MainThread> thread = sptr<MainThread>(new (std::nothrow) MainThread());
- ......
- thread->Init(runner);
- thread->Attach(); }
- void MainThread::Init()
- {
- auto task = [weak]() {
- auto appThread = weak.promote();
- appThread->SetRunnerStarted(true);
- };
- if (!mainHandler_->PostTask(task)) {
- HILOG_ERROR("MainThread::Init PostTask task failed");
- }
- watchdog_->Init(mainHandler_);
- extensionConfigMgr_->Init();
- }
- void MainThread::Attach()
- {
- if (!ConnectToAppMgr()) {
- return;
- }
- mainThreadState_ = MainThreadState::ATTACH;
- }
- bool MainThread::ConnectToAppMgr()
- {
- auto object = OHOS::DelayedSingleton<SysMrgClient>::GetInstance()->GetSystemAbility(APP_MGR_SERVICE_ID);
- appMgr_ = iface_cast<IAppMgr>(object);
- appMgr_->AttachApplication(this);
- }
复制代码
客户端发送 attach application 请求
foundation\ability\ability_runtime\interfaces\inner_api\app_manager\src\appmgr\app_mgr_proxy.cpp
- AppMgrProxy::AttachApplication(const sptr<IRemoteObject> &obj)
- {
- sptr<IRemoteObject> remote = Remote();
- remote->SendRequest(static_cast<uint32_t>(IAppMgr::Message::APP_ATTACH_APPLICATION), ...);
- }
复制代码
服务端收到 attach application 请求
foundation\ability\ability_runtime\interfaces\inner_api\app_manager\src\appmgr\app_mgr_stub.cpp
- int32_t AppMgrStub::HandleAttachApplication(MessageParcel &data, MessageParcel &reply)
- {
- sptr<IRemoteObject> client = data.ReadRemoteObject();
- AttachApplication(client);
- }
复制代码
foundation\ability\ability_runtime\services\appmgr\src\app_mgr_service.cpp
- void AppMgrService::AttachApplication(const sptr<IRemoteObject> &app)
- {
- pid_t pid = IPCSkeleton::GetCallingPid();
- AddAppDeathRecipient(pid);
- std::function<void()> attachApplicationFunc =
- std::bind(&AppMgrServiceInner::AttachApplication, appMgrServiceInner_, pid, iface_cast<IAppScheduler>(app));
- taskHandler_->SubmitTask(attachApplicationFunc, TASK_ATTACH_APPLICATION);
- }
复制代码
函数处理逻辑回到服务层
foundation\ability\ability_runtime\services\appmgr\src/app_mgr_service_inner.cpp
- void AppMgrServiceInner::AttachApplication(const pid_t pid, const sptr<IAppScheduler> &appScheduler)
- {
- ......
- appRecord->SetApplicationClient(appScheduler);
- appRecord->RegisterAppDeathRecipient();
- if (appRecord->GetState() == ApplicationState::APP_STATE_CREATE) {
- LaunchApplication(appRecord);
- }
- eventInfo.pid = appRecord->GetPriorityObject()->GetPid();
- eventInfo.processName = appRecord->GetProcessName();
- AAFwk::EventReport::SendAppEvent(AAFwk::EventName::APP_ATTACH, HiSysEventType::BEHAVIOR, eventInfo);
- }<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;">
- </span></p></div></div>void AppMgrServiceInner::LaunchApplication(const std::shared_ptr<AppRunningRecord> &appRecord)
- {
- appRecord->LaunchApplication(*configuration_);
- appRecord->SetState(ApplicationState::APP_STATE_READY);
- appRecord->SetRestartResidentProcCount(restartResidentProcCount);
- ......
- appRecord->LaunchPendingAbilities();
- AAFwk::EventReport::SendAppEvent(AAFwk::EventName::APP_LAUNCH, HiSysEventType::BEHAVIOR, eventInfo);
- }
复制代码 2.应用初始化,通过AppRunningRecord调用LaunchApplication应用第一次启动时,会先创建AppRunningRecord
foundation\ability\ability_runtime\services\appmgr\src\app_running_record.cpp
- void AppRunningRecord::LaunchApplication(const Configuration &config)
- {
- appLifeCycleDeal_->GetApplicationClient()
- ......
- launchData.SetProcessInfo(processInfo);
- launchData.SetRecordId(appRecordId_);
- launchData.SetUId(mainUid_);
- launchData.SetUserTestInfo(userTestRecord_);
- launchData.SetAppIndex(appIndex_);
- appLifeCycleDeal_->LaunchApplication(launchData, config);
- }
复制代码
foundation\ability\ability_runtime\services\appmgr\src\app_lifecycle_deal.cpp
- void AppLifeCycleDeal::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
- {
- appThread_->ScheduleLaunchApplication(launchData, config);
- }
复制代码
处理启动应用(加载依赖库、初始化资源管理器等)等逻辑
foundation\ability\ability_runtime\frameworks\native\appkit\app\main_thread.cpp
- void MainThread::ScheduleLaunchApplication(const AppLaunchData &data, const Configuration &config)
- {
- appThread->HandleLaunchApplication(data, config);
- }
- void MainThread::HandleLaunchApplication(const AppLaunchData &data, const Configuration &config)
- {
- if (!InitCreate(contextDeal, appInfo, processInfo)) {
- return;
- }
- if (IsNeedLoadLibrary(bundleName)) {
- ChangeToLocalPath(bundleName, appInfo.moduleSourceDirs, localPaths);
- LoadAbilityLibrary(localPaths);
- LoadNativeLiabrary(bundleInfo, appInfo.nativeLibraryPath);
- }
- if (appInfo.needAppDetail) {
- LoadAppDetailAbilityLibrary(appInfo.appDetailAbilityLibraryPath);
- }
- LoadAppLibrary();
- if (isStageBased) {
- AppRecovery::GetInstance().InitApplicationInfo(GetMainHandler(), GetApplicationInfo());
- }
- // create contextImpl
- ......
- if (isStageBased) {
- // Create runtime
- ......
- application_->SetRuntime(std::move(runtime));
- AbilityLoader::GetInstance().RegisterAbility("Ability", [application = application_]() {
- return Ability::Create(application->GetRuntime());
- });
- LoadAllExtensions(jsEngine);
- contextDeal->initResourceManager(resourceManager);
- contextDeal->SetApplicationContext(application_);
- application_->AttachBaseContext(contextDeal);
- application_->SetAbilityRecordMgr(abilityRecordMgr_);
- application_->SetConfiguration(config);
- contextImpl->SetConfiguration(application_->GetConfiguration());
- applicationImpl_->SetRecordId(appLaunchData.GetRecordId());
- applicationImpl_->SetApplication(application_);
- mainThreadState_ = MainThreadState::READY;
- ......
- applicationImpl_->PerformAppReady()
- nwebMgr->PreStartNWebSpawnProcess();
- ......
- // init resourceManager.
- ......
- }
复制代码
3. 通过RunningRecord调用LaunchPendingAbilities,最终创建Abilityfoundation\ability\ability_runtime\services\appmgr\src/module_running_record.cpp
- void ModuleRunningRecord::LaunchPendingAbilities()
- {
- for (const auto &item : abilities_) {
- const auto &ability = item.second;
- if (ability->GetState() == AbilityState::ABILITY_STATE_CREATE && ability->GetToken() &&
- appLifeCycleDeal_->GetApplicationClient()) {
- appLifeCycleDeal_->LaunchAbility(ability);
- ability->SetState(AbilityState::ABILITY_STATE_READY);
- }
- }
- }
- void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
- {
- appLifeCycleDeal_->LaunchAbility(ability);
- ability->SetState(AbilityState::ABILITY_STATE_READY);
- }
复制代码
通过IPC调用ScheduleLaunchAbility函数
foundation\ability\ability_runtime\services\appmgr\src/app_lifecycle_deal.cpp
- AppLifeCycleDeal::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
- {
- if (appThread_ && ability) {
- appThread_->ScheduleLaunchAbility(*(ability->GetAbilityInfo()), ability->GetToken(),
- ability->GetWant());
- }
- }
复制代码
foundation\ability\ability_runtime\frameworks\native\appkit\app\main_thread.cpp
- MainThread::ScheduleLaunchAbility(const AbilityInfo &info, const sptr<IRemoteObject> &token, const std::shared_ptr<AAFwk::Want> &want)
- {
- auto task = [weak, abilityRecord]() {
- ...
- auto appThread = weak.promote();
- appThread->HandleLaunchAbility(abilityRecord);
- };
- mainHandler_->PostTask(task);
- }
- MainThread::HandleLaunchAbility(const std::shared_ptr<AbilityLocalRecord> &abilityRecord)
- {
- abilityRecordMgr_->SetToken(abilityToken);
- abilityRecordMgr_->AddAbilityRecord(abilityToken, abilityRecord);
- //创建AbilityStage
- std::shared_ptr<AbilityRuntime::Context> stageContext = application_->AddAbilityStage(abilityRecord);
- //启动Ability线程
- AbilityThread::AbilityThreadMain(application_, abilityRecord, stageContext);
- }
复制代码
foundation\ability\ability_runtime\frameworks\native\appkit\app\ohos_application.cpp
- bool OHOSApplication::AddAbilityStage(const AppExecFwk::HapModuleInfo &hapModuleInfo)
- {
- ......
- auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
- stageContext->SetParentContext(abilityRuntimeContext_);
- stageContext->InitHapModuleInfo(hapModuleInfo);
- stageContext->SetConfiguration(GetConfiguration());
- auto abilityStage = AbilityRuntime::AbilityStage::Create(runtime_, *moduleInfo);
- abilityStage->Init(stageContext);
- Want want;
- abilityStage->OnCreate(want);
- abilityStages_[hapModuleInfo.moduleName] = abilityStage;
- return true;
- }
复制代码
foundation\ability\ability_runtime\frameworks\native\appkit\ability_runtime\app\ability_stage.cpp
- std::shared_ptr<AbilityStage> AbilityStage::Create(
- const std::unique_ptr<Runtime>& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo)
- {
- ......
- switch (runtime->GetLanguage()) {
- case Runtime::Language::JS:
- return JsAbilityStage::Create(runtime, hapModuleInfo);
- default:
- return std::make_shared<AbilityStage>();
- }
- }
- void AbilityStage::AddAbility(const sptr<IRemoteObject> &token,
- const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &abilityRecord)
- {
- ......
- abilityRecords_[token] = abilityRecord;
- }
复制代码 foundation\ability\ability_runtime\frameworks\native\appkit\ability_runtime\app\ability_stage.cpp
- td::shared_ptr<AbilityStage> JsAbilityStage::Create(){
- auto& jsRuntime = static_cast<JsRuntime&>(*runtime);
- std::string srcPath(hapModuleInfo.name);
- std::string moduleName(hapModuleInfo.moduleName);
- moduleName.append("::").append("AbilityStage");
- ......
- //srcPath.append("/assets/js/");
- //srcPath.append("AbilityStage.abc");
- srcPath.append(hapModuleInfo.srcPath);
- srcPath.append("/AbilityStage.abc");
- auto moduleObj = jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath,
- hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, commonChunkFlag);
- return std::make_shared<JsAbilityStage>(jsRuntime, std::move(moduleObj));
- }
- void JsAbilityStage::Init(const std::shared_ptr<Context> &context)
- {
- AbilityStage::Init(context);
- }
- void JsAbilityStage::OnCreate(const AAFwk::Want &want) const
- {
- AbilityStage::OnCreate(want);
- ......
- auto& nativeEngine = jsRuntime_.GetNativeEngine();
- NativeValue* value = jsAbilityStageObj_->Get();
- nativeEngine.CallFunction(value, methodOnCreate, nullptr, 0);
- }
- //AbilityStage
- void AbilityStage::Init(const std::shared_ptr<Context>& context){
- context_ = context;
- }
- void AbilityStage::OnCreate(const AAFwk::Want &want) cons{
- HILOG_DEBUG("AbilityStage OnCreate come.");
- }
复制代码
foundation\ability\ability_runtime\frameworks\native\ability\native\ability_thread.cpp
至此,关于应用启动过程中application和ability初始化梳理清楚,OpenHarmony的源码关键Api和源码路径也都列举了出来,有疑问可自行获取源码加深理解。
四、总结-时序图
本文基于以上源码分析进行了总结,绘制了时序图,如下图所示。
(, 下载次数: 4)
五、参考链接
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
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) |
Powered by Discuz! X3.5 |