返回键是否致应用退出问题分析报告

鸿蒙小紫娃 2023-03-13 18:49:50

1 关键字

onDestroy;应用退出;OnBackPressed;

2 问题描述

OH版本:3.1 Release
ets API版本: 8

点击界面返回键,用户应用会退出,触发PAGE onDestroy生命周期,对应系统应用例如Launcher应用则不会退出,对此系统如何区分应用

3 流程分析

正常情况下,点击“后退”按钮,系统发送keyevent。
从源码上看流程大致如下:

后退按钮属于系统systemui应用:

点击后退按钮,会向系统发送BackKeyEventKeyCodeEvent

// applications_systemui\features\navigationservice\src\main\ets\com\ohos\navigationservice\KeyCodeEvent.ts
export class KeyCodeEvent {
  public sendKeyEvent(keyCode: number, eventType: number) {   
    switch (keyCode) {
      case Constants.KEYCODE_BACK:
          this.sendBackKeyEventStart(); //down
          ...
          this.sendBackKeyEventEnd(); //up

这个事件会传递到ACE UI子系统下的 Ability 及 AceContainer:

// foundation\ace\ace_engine\adapter\ohos\entrance\ace_container.cpp
bool AceContainer::OnBackPressed(int32_t instanceId)
{
    ...
    //执行PipelineContext Router相关函数
    return context->CallRouterBackToPopPage();
}

PipelineContext::CallRouterBackToPopPage 执行到 DeclarativeFrontend::CallRouterBack(\bridge\declarative_frontend\declarative_frontend.cpp)... 直至FrontendDelegateDeclarative::PopPage

// frameworks\bridge\declarative_frontend\frontend_delegate_declarative.cpp
void FrontendDelegateDeclarative::PopPage()
{
    ...
    if (delegate->GetStackSize() == 1) {
        // 不允许继续后退页面
        if (delegate->disallowPopLastPage_) {
            LOGW("Not allow back because this is the last page!");
        }
        //应用生命周期相关函数入口
        delegate->OnPageHide();
        delegate->OnPageDestroy(delegate->GetRunningPageId());
       ...

disallowPopLastPage_的值与应用的isLauncherAbility属性关联:

// ace_container.cpp: AceContainer::InitializeFrontend
if (info && info->isLauncherAbility) {
        frontend_->DisallowPopLastPage();
    }

isLauncherAbility的值基于应用内 ability.skills.entities是否包含 "flag.home.intent.from.system"来确定,在系统Launcher应用内基于配置信息( API9:module.json 或api<9: config.json)该值为true :

const std::string FLAG_HOME_INTENT_FROM_SYSTEM = "flag.home.intent.from.system";

//appexecfwk\standard\services\bundlemgr\src\module_profile.cpp

// API9 获取 launcher信息
bool isLauncherEntity = std::find(skill.entities.begin(), skill.entities.end(),
    Constants::FLAG_HOME_INTENT_FROM_SYSTEM) != skill.entities.end();
if (isLauncherEntity && isPreInstallApp) {
    applicationInfo.isLauncherApp = true;
    abilityInfo.isLauncherAbility = true;
}
// API8: applications_launcher/product/pad/src/main/module.json5
"extensionAbilities": [
      {
        "priority": 2,
        "skills": [
          {
            "entities": [
              "entity.system.home",
              "flag.home.intent.from.system"
            ],
// API9: applications_launcher/product/phone/src/main/config.json
"abilities": [
      {
        "skills": [
          {
            "entities": [
              "entity.system.home",
              "flag.home.intent.from.system"
            ],
          }
        ],

4 总结

点击界面返回键,用户应用会退出,系统应用例如Launcher应用不会退出

...全文
7 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

421

社区成员

发帖
与我相关
我的任务
社区描述
OpenHarmony开发者社区
其他 企业社区
社区管理员
  • csdnsqst0025
  • shewaliujingli
  • BaoWei
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧