文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一篇带你了解Ability启动过程

2024-11-30 16:52

关注

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个Ability),OpenHarmony OS支持应用以Ability为单位进行部署。Ability可以分为FA(Feature Ability)和PA(Particle Ability)两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。

以上摘自官方文档,本文简要介绍Page应用(AceAbility为例)启动过程 ,减少入手难度。

1、AppSpawn进程响应应用start请求

启动应用命令:

aa start -a <ability-name> -b <bundle-name>
e.g. aa start -a com.example.myapplication.MainAbility -b com.example.myapplication
//startup/appspawn/standard/appspawn_service.c
appspawn_service.c 调用OnReceiveRequest()处理请求,fork子进程 *childPid = AppSpawnFork(AppSpawnChild, (void *)sandbox);

2、fork子进程(aka.应用)

//base/startup/appspawn/common/appspawn_server.c
*childPid = AppSpawnFork(AppSpawnChild, (void *)sandbox);

AppSpawnChild中执行应用启动前步骤,如清理环境、权限鉴权等后,调用content->runChildProcessor(content, client)。

3、应用主线程Start

//startup/appspawn/adapter/appspawn_ace.cpp

在Start()中装备应用MainThread的EventRunner和MainHandler,在EventRunner::Run等待event分发处理和event循环,这里是应用的主线程,也负责拉起其他的线程。这里有必要简要说明OHOS的事件通知机制。

ohos基础框架中的notification机制

代码路径:

OHOS event-notification机制可以保证一个线程中可以安全地向其他线程投递任务,只要拿到其他线程的Handler或者EventRunner即可。

UML类图:

说明:

(1). EventHandler负责投递封装好的event到EventRunner的EventQueue中,并提供ProcessEvent接口供子类重写业务逻辑。

(2). EventRunner负责线程运行的抽象,实际线程运行委托给EventInnerRunner实现。

(3). EventInnerRunner/EventRunnerImpl类是线程运行具体实现,提供ThreadMain()作为std::thread运行入口,在Run()完成event分发处理和event循环(EventHanlder在投递event时候,将handler本身封装在event中,之所以这样做,可能是为了同时支持callback型task和EventHandler中重写ProcessEvent处理方式)。

4、MainThread::Init初始化

拉起看DFX的看门狗线程和信号处理线程,设置应用主线程状态。

5、向AMS注册应用,并调度运行

应用调用Attach(),需要向AMS注册表项资源。

MainThread是IRemoteStub子类,向AMS注册反向死亡通知,应用退出能及时释放AMS相关资源。

获取AppMgr Proxy对象 AttachApplication之后,AMS调度Application状态。

说明:

MainThread、AMS、ABMS运行在不同进程中,其中AMS、ABMS是SA,使用ohos IPC机制通信。

1.MainThread 是IRemoteStub 子类,是一个匿名IPC对象(匿名这里指的是没有注册到samgr,无said),反向死亡通知到AMS,应用结束时候可以通知AMS回收已分配的AppRunningRecord资源。

2.AppThread(应用主线程,即MainThread)向AMS发送APP_ATTACH_APPLICATION请求并置MainThread状态为Attach,AMS侧收到请求创建appRecord,标记APP_STATE_CREATE。

3.AMS判断appRecord 为ApplicationState::APP_STATE_CREATE,向Application发送SCHEDULE_LAUNCH_APPLICATION_TRANSACTION请求。

4.AMS标记appRecord状态为APP_STATE_READY。

5.AppThread接收到AMS的SCHEDULE_LAUNCH_APPLICATION_TRANSACTION请求后,调用ScheduleLaunchApplication向MainThread投递任务。

void MainThread::ScheduleLaunchApplication(const AppLaunchData &data, const Configuration &config)
{
......
wptr<MainThread> weak = this;
auto task = [weak, data, config]()
{
auto appThread = weak.promote();
if (appThread == nullptr)
{
HILOG_ERROR("appThread is nullptr, HandleLaunchApplication failed.");
return;
}
appThread->HandleLaunchApplication(data, config);
};
if (!mainHandler_->PostTask(task))
......
}

该task被执行时调用MainThread::HandleLaunchApplication,调用LoadAbilityLibrary(如加载libace.z.so等库保存句柄)、LoadNativeLiabrary、LoadAppLibrary、设置Application上下文信息、从BundleMgr获取Bundle信息、初始化资源管理器InitResourceManager。(此处有区分应用模型,一般是FA模型或者Stage,不做详细介绍,有兴趣自己研究)。

6.AppThread收到AMS的SCHEDULE_LAUNCH_ABILITY_TRANSACTION请求,调用HandleLaunchAbility()->AbilityThread::AbilityThreadMain(),创建AbilityThread,调用AbilityThread::Attach(),依据AbilityType创建相应的Ability(这里以AceAbility为例),初始化Ability 。

Ability 初始化这里有几处值得注意。

(1)、Ability有若干类型如: AceAbility、AceFormAbility、AceServiceAbility、AceDataAbility等,代码中有相关类。

(2)、创建AbilityThread的AbilityHandler时候,将MainEventRunner 作为参数传入,因此AbilityThread用的还是MainEventRunner事件循环。

(3)、在这里创建AbilityWindow(初始化等到Ability的OnStart)、注册监听(AbilityWindow和图形相关,比较重要)。

if (info && info->type == AbilityType::PAGE) {
ability_->SetSceneListener(
sptr<WindowLifeCycleImpl>(new WindowLifeCycleImpl(token_, shared_from_this())));
}

备注:AMS在AppMgrServiceInner::LaunchApplication中会调用appRecord->LaunchPendingAbilities(),调度应用Ability,感兴趣可以自行研究。

void AbilityThread::Attach(std::shared_ptr<OHOSApplication> &application,
const std::shared_ptr<AbilityLocalRecord> &abilityRecord, const std::shared_ptr<EventRunner> &mainRunner,
const std::shared_ptr<AbilityRuntime::Context> &stageContext)
{
// 1.new AbilityHandler 根据不同AbilityType获得abilityName
std::string abilityName = CreateAbilityName(abilityRecord, application);
if (abilityName == "") {
HILOG_ERROR("Attach ability failed, abilityInfo is nullptr.");
return;
}
HILOG_DEBUG("Attach ability begin, ability:%{public}s.", abilityRecord->GetAbilityInfo()->name.c_str());
abilityHandler_ = std::make_shared<AbilityHandler>(mainRunner);
if (abilityHandler_ == nullptr) {
HILOG_ERROR("Attach ability failed, abilityHandler_ is nullptr.");
return;
}

// 2.new ability 创建不同的ability,这里以AceAbility为例
auto ability = AbilityLoader::GetInstance().GetAbilityByName(abilityName);
if (ability == nullptr) {
HILOG_ERROR("Attach ability failed, load ability failed.");
return;
}
......
// 3.new abilityImpl
abilityImpl_ =
DelayedSingleton<AbilityImplFactory>::GetInstance()->MakeAbilityImplObject(abilityRecord->GetAbilityInfo());
if (abilityImpl_ == nullptr) {
HILOG_ERROR("Attach ability failed, abilityImpl_ == nullptr.");
return;
}
// 这里初始化abilityWindow及AbilityLifeCycle
abilityImpl_->Init(application, abilityRecord, currentAbility_, abilityHandler_, token_, contextDeal);
// 4. ability attach : ipc
ErrCode err = AbilityManagerClient::GetInstance()->AttachAbilityThread(this, token_);
if (err != ERR_OK) {
HILOG_ERROR("Attach ability failed, err = %{public}d.", err);
return;
}

7.调用AttachAbilityThread ,want:PARAM_RESV_CALL_TO_FOREGROUND,将Ability调度到前端。

8.ABMS发送ATTACH_ABILITY_THREAD请求到AMS。

9.AMS调用AppThread->ScheduleForegroundApplication()。

10.App线程调用ScheduleForegroundApplication主要是设置App状态,并发送APP_APPLICATION_FOREGROUNDED通知AMS。

if (((curState_ == APP_STATE_READY) || (curState_ == APP_STATE_BACKGROUND)) && application_ != nullptr) {
application_->OnForeground();
curState_ = APP_STATE_FOREGROUND;
return true;
}

11.AMS收到请求,标记相应AppRecord状态为ApplicationState::APP_STATE_FOREGROUND,应用和AMS进程状态同步。

备注:后续AMS触发ABMS调用ScheduleAbilityTransaction调用PageAbilityImpl::HandleAbilityTransaction()->AceAbility::OnStart()、Ability::OnStart() InitWindow初始化窗口、加载Dom控件树、图形渲染等。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

来源:51CTO 开源基础软件社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯