OpenHarmony南向开发:启动流程分析(Application&Ability初始化)

30 篇文章 0 订阅
5 篇文章 0 订阅

往期鸿蒙全套实战精彩文章必看内容:


一、引言

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

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

1. 启动框架须知

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

图片

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);
}

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,最终创建Ability

foundation\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\js_ability_stage.cpp

std::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

void AbilityThread::AbilityThreadMain(
    std::shared_ptr<OHOSApplication> &application, const std::shared_ptr<AbilityLocalRecord> &abilityRecord,
    const std::shared_ptr<AbilityRuntime::Context> &stageContext){
    //Attach The ability thread to the main process
    thread->Attach(application, abilityRecord, stageContext);
}

void AbilityThread::Attach(
    std::shared_ptr<OHOSApplication> &application, const std::shared_ptr<AbilityLocalRecord> &abilityRecord,
    const std::shared_ptr<AbilityRuntime::Context> &stageContext){
   // 1.new AbilityHandler 根据不同AbilityType获得abilityName
    std::string abilityName = CreateAbilityName(abilityRecord, application);
    runner_ = EventRunner::Create(abilityName);
    abilityHandler_ = std::make_shared<AbilityHandler>(runner_);
    // 2.new ability
    auto ability = AbilityLoader::GetInstance().GetAbilityByName(abilityName);
    currentAbility_.reset(ability);
    token_ = abilityRecord->GetToken();
    abilityRecord->SetEventHandler(abilityHandler_);
    abilityRecord->SetEventRunner(runner_);
    abilityRecord->SetAbilityThread(this);
    ability->AttachBaseContext(contextDeal);
    // new hap requires
    ability->AttachAbilityContext(BuildAbilityContext(abilityRecord->GetAbilityInfo(), application, token_,
        stageContext));
    // 3.new abilityImpl 
    abilityImpl_ = DelayedSingleton<AbilityImplFactory>::GetInstance()->MakeAbilityImplObject(abilityRecord->GetAbilityInfo());
    //Ability初始化操作
    abilityImpl_->Init(application, abilityRecord, currentAbility_, abilityHandler_, token_, contextDeal);
    // 4. ability attach : ipc
    ErrCode err = AbilityManagerClient::GetInstance()->AttachAbilityThread(this, token_);
}

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

四、总结-时序图

图片

看完三件事❤️

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注作者 ,不定期分享原创知识。
  • 同时可以期待后续文章ing🚀。   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值