OpenHarmony应用启动流程分析——Application&Ability初始化

一、引言

本文基于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端

foundationabilityability_runtimeframeworksnativeappkitappmain_thread.cpp


 void MainThread::Start() 
 {
     sptr thread = sptr(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::GetInstance()->GetSystemAbility(APP_MGR_SERVICE_ID);
    appMgr_ = iface_cast(object);
    appMgr_->AttachApplication(this);  
}

客户端发送 attach application 请求foundationabilityability_runtimeinterfacesinner_apiapp_managersrcappmgrapp_mgr_proxy.cpp


AppMgrProxy::AttachApplication(const sptr &obj)
{
    sptr remote = Remote();
    remote->SendRequest(static_cast(IAppMgr::Message::APP_ATTACH_APPLICATION), ...);
}

服务端收到 attach application 请求foundationabilityability_runtimeinterfacesinner_apiapp_managersrcappmgrapp_mgr_stub.cpp

int32_t AppMgrStub::HandleAttachApplication(MessageParcel &data, MessageParcel &reply)
{
    sptr client = data.ReadRemoteObject();
    AttachApplication(client);  
}

foundationabilityability_runtimeservicesappmgrsrcapp_mgr_service.cpp

void AppMgrService::AttachApplication(const sptr &app)
{
   pid_t pid = IPCSkeleton::GetCallingPid();
    AddAppDeathRecipient(pid);
    std::function attachApplicationFunc =
        std::bind(&AppMgrServiceInner::AttachApplication, appMgrServiceInner_, pid, iface_cast(app));
    taskHandler_->SubmitTask(attachApplicationFunc, TASK_ATTACH_APPLICATION);
}

函数处理逻辑回到服务层foundationabilityability_runtimeservicesappmgrsrc/app_mgr_service_inner.cpp


void AppMgrServiceInner::AttachApplication(const pid_t pid, const sptr &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 &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

应用第一次启动时,会先创建AppRunningRecordfoundationabilityability_runtimeservicesappmgrsrcapp_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);
}

foundationabilityability_runtimeservicesappmgrsrcapp_lifecycle_deal.cpp

void AppLifeCycleDeal::LaunchAbility(const std::shared_ptr &ability)
{
    appThread_->ScheduleLaunchApplication(launchData, config);
}

处理启动应用(加载依赖库、初始化资源管理器等)等逻辑foundationabilityability_runtimeframeworksnativeappkitappmain_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

foundationabilityability_runtimeservicesappmgrsrc/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 &ability)
{
    appLifeCycleDeal_->LaunchAbility(ability);
    ability->SetState(AbilityState::ABILITY_STATE_READY);
}

通过IPC调用ScheduleLaunchAbility函数
foundationabilityability_runtimeservicesappmgrsrc/app_lifecycle_deal.cpp

AppLifeCycleDeal::LaunchAbility(const std::shared_ptr &ability)
{
    if (appThread_ && ability) {
        appThread_->ScheduleLaunchAbility(*(ability->GetAbilityInfo()), ability->GetToken(),
            ability->GetWant());
    }
}

foundationabilityability_runtimeframeworksnativeappkitappmain_thread.cpp

MainThread::ScheduleLaunchAbility(const AbilityInfo &info, const sptr &token, const std::shared_ptr<:want> &want)
{
    auto task = [weak, abilityRecord]() {
        ...
        auto appThread = weak.promote();
        appThread->HandleLaunchAbility(abilityRecord);
    };
    mainHandler_->PostTask(task);
}
 MainThread::HandleLaunchAbility(const std::shared_ptr &abilityRecord)
 {
    abilityRecordMgr_->SetToken(abilityToken);
    abilityRecordMgr_->AddAbilityRecord(abilityToken, abilityRecord);
    //创建AbilityStage
    std::shared_ptr<:context> stageContext = application_->AddAbilityStage(abilityRecord);
    //启动Ability线程
    AbilityThread::AbilityThreadMain(application_, abilityRecord, stageContext);  
 }

foundationabilityability_runtimeframeworksnativeappkitappohos_application.cpp

bool OHOSApplication::AddAbilityStage(const AppExecFwk::HapModuleInfo &hapModuleInfo)
{
     ......
    auto stageContext = std::make_shared<: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;
}

foundationabilityability_runtimeframeworksnativeappkitability_runtimeappability_stage.cpp

std::shared_ptr AbilityStage::Create(
    const std::unique_ptr& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo)
{
    ......
    switch (runtime->GetLanguage()) {
        case Runtime::Language::JS:
            return JsAbilityStage::Create(runtime, hapModuleInfo);
        default:
            return std::make_shared();
    }
}

void AbilityStage::AddAbility(const sptr &token,
    const std::shared_ptr<:abilitylocalrecord> &abilityRecord)
{
    ......
    abilityRecords_[token] = abilityRecord;
}

foundationabilityability_runtimeframeworksnativeappkitability_runtimeappjs_ability_stage.cpp

std::shared_ptr JsAbilityStage::Create(){
    auto& jsRuntime = static_cast(*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(jsRuntime, std::move(moduleObj));
}

void JsAbilityStage::Init(const std::shared_ptr &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;
}
void AbilityStage::OnCreate(const AAFwk::Want &want) cons{
    HILOG_DEBUG("AbilityStage OnCreate come.");
}

foundationabilityability_runtimeframeworksnativeabilitynativeability_thread.cpp


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

void AbilityThread::Attach(
    std::shared_ptr &application, const std::shared_ptr &abilityRecord,
    const std::shared_ptr<:context> &stageContext){
   // 1.new AbilityHandler 根据不同AbilityType获得abilityName
    std::string abilityName = CreateAbilityName(abilityRecord, application);
    runner_ = EventRunner::Create(abilityName);
    abilityHandler_ = std::make_shared(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::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和源码路径也都列举了出来,有疑问可自行阅读源码加深理解。

四、总结-时序图

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21744,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?