返回键是否致应用退出问题分析报告
1 关键字 onDestroy;应用退出;OnBackPressed; 2 问题描述 OH版本:3.1 Release ets API版本: 8 点击界面返回键,用户应用会退出,触发PAGE onDestroy生命周期,对应系统应用例如Launcher应用则不会退出,对此系统如何区分应用 3 流程分析 正常情况下,点击“后退”按钮,系统发送keyevent。 从源码上看流程大致如下: 后退按钮属于
1 关键字
系统应用;OnBackPressed;
2 问题描述
用户自定义的桌面应用,替换系统应用Launcher,点击界面返回键,应系统应用Launcher退出。
3 问题原因
3.1 正常机制
点击界面返回键,应系统应用Launcher不会退出。
3.2 异常机制
点击界面返回键,应系统应用Launcher退出。
4 解决方案
应用配置信息 skills.entities项添加 "flag.home.intent.from.system"
5 定位过程
正常情况下,点击后退按钮,会向系统发送BackKeyEvent
KeyCodeEvent
// 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.json5 或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;
}
应用配置信息:
//applications_launcher/product/phone/src/main/module.json5
"abilities": [
{
"skills": [
{
"entities": [
],
}
],
用户自定义的Launcher应用skills.entities没有"flag.home.intent.from.system"项,应用未被判定为系统桌面应用,因此点击返回键触发应用退出逻辑。
6 知识分享
应用配置配置文件 skills标签标识UIAbility组件或者ExtensionAbility组件能够接收的Want的特征。其中字段entities表示目标应用组件的类别信息。
更多推荐
所有评论(0)