HarmonyOS鸿蒙Next中请教关于关闭应用的方法逻辑及实现方式

HarmonyOS鸿蒙Next中请教关于关闭应用的方法逻辑及实现方式

客户端设计逻辑

用户通过点击主菜单中的退出选项,会触发一个弹窗,用于确认是否真的退出。图示如下:

当再次点击“狠心退出”按钮时,当前客户端将会关闭,即游戏应用被关闭。

当前功能代码

通过查阅相关信息,目前实现“退出”功能的代码如下:

Button('狠心退出')
    .type(ButtonType.Capsule)
        .fontColor(Color.White)
        .fontSize(25)
        .backgroundColor(Color.Transparent)
        .onClick(() => {
            this.controller.close();
            (this.getUIContext().getHostContext() as common.UIAbilityContext)?.terminateSelf();
            })

请教问题

想请教下各位佬,当前代码对应用退出功能的实现方式是否妥当,需要做哪些额外的隐患排查或是应该使用其他方式实现这个功能。


更多关于HarmonyOS鸿蒙Next中请教关于关闭应用的方法逻辑及实现方式的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

terminateSelf用于Stage模型中销毁当前UIAbility实例,仅支持在主线程调用,避免多线程操作冲突。可以使用terminateSelf安全的退出应用,参考示例:

try {
  let uicontext = getContext(this) as common.UIAbilityContext
  uicontext.terminateSelf((err: BusinessError) => {
    if (err.code) {
      // 处理业务逻辑错误
      console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);
      return;
    }
    // 执行正常业务
    console.info('terminateSelf succeed');
  });
} catch (err) {
  // 捕获同步的参数错误
  let code = (err as BusinessError).code;
  let message = (err as BusinessError).message;
  console.error(`terminateSelf failed, code is ${code}, message is ${message}`);
}

调用terminateSelf可以停止当前的UIAbility实例。如需要关闭应用所有的UIAbility实例,可以调用ApplicationContext的killAllProcesses()方法实现关闭应用所有的进程。 注意: 调用terminateSelf()方法和killAllProcesses()方法停止或关闭UIAbility实例时,默认会保留该实例的快照(Snapshot),即在最近任务列表中仍然能查看到该实例对应的任务。如不需要保留该实例的快照,可以在其对应UIAbility的module.json5配置文件中,将Abilities标签的removeMissionAfterTerminate字段配置为true。

更多关于HarmonyOS鸿蒙Next中请教关于关闭应用的方法逻辑及实现方式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


除了通过按钮主动退出应用外,还需要考虑用户通过手机系统返回键的处理【例如手势导航模式中的左右滑返回】;结合您的代码作出如下示例

const context = getContext(this) as common.UIAbilityContext
//...
 
 Button('狠心退出')
    .type(ButtonType.Capsule)
        .fontColor(Color.White)
        .fontSize(25)
        .backgroundColor(Color.Transparent)
        .onClick(() => {
            this.controller.close();
            context.terminateSelf();
         })

 //...

 //监听系统返回键
 onBackPress(): boolean | void {
    this.controller.close();
    context.terminateSelf()
    return false
  }

关键细节

  • return true/false:控制是否拦截返回键的默认行为(true 不拦截,false 拦截,确保退出时生效)。
  • context.terminateSelf():退出当前应用的核心方法(销毁当前组件 / 应用进程)。

建议:一定时间内的双击才退出,加强用户体验,以免误触

  • 新增一个页面的时间计数器
  • 实现「1.5 秒内连续按两次返回键才退出程序」的效果,单次点击仅提示用户。
  • 例如:
    import promptAction from '@ohos.promptAction'
    
    //...
    private timeStart = 0
    
    onExit(){
      if (this.timeStart == 0) {
          this.timeStart = systemDateTime.getTime()
          promptAction.showToast({ message:"确定要狠心退出吗"})
        } else {
          if (systemDateTime.getTime() - this.timeStart > 1500) {
            promptAction.showToast({ message:"再按一次狠心退出"})
            this.timeStart = systemDateTime.getTime()
          } else {
            context.terminateSelf()
          }
        }
     }
    

楼主你好:

(this.getUIContext().getHostContext() as common.UIAbilityContext)?.terminateSelf();

你的退出方法是正确的,合理的!

退出应用:terminateSelf

terminateSelf(callback: AsyncCallback<void>): void

销毁UIAbility自身。使用callback异步回调。仅支持在主线程调用。官方示例代码中加入了try、catch。

import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
  onForeground() {
    try {
      this.context.terminateSelf((err: BusinessError) => {
        if (err.code) {
          // 处理业务逻辑错误
          console.error(`terminateSelf failed, code is ${err.code}, message is ${err.message}`);
          return;
        }
        // 执行正常业务
        console.info('terminateSelf succeed');
      });
    } catch (err) {
      // 捕获同步的参数错误
      let code = (err as BusinessError).code;
      let message = (err as BusinessError).message;
      console.error(`terminateSelf failed, code is ${code}, message is ${message}`);
    }
  }
}

(可选)如果需要在停止UIAbility时,清理任务中心的相关任务(即不保留最近任务列表中的快照),需要在module.json5配置文件中将removeMissionAfterTerminate字段取值配置为true。

{
  "module": {
    // ...
    "abilities": [
      {
        // ...
        "removeMissionAfterTerminate": true
      }
    ]
  }
}

在HarmonyOS Next中,关闭应用主要通过UIAbility的terminateSelf()方法实现。该方法会销毁当前Ability实例并释放资源。若需关闭整个应用进程,可调用process.exit()。开发者可在应用退出前于onWindowStageDestroy()生命周期回调中执行资源清理。注意:系统会管理应用生命周期,不建议强制终止。

在HarmonyOS Next中,你提供的代码逻辑基本正确,但存在一处关键冗余和一处潜在隐患,可以优化。

  1. 冗余操作this.controller.close(); 这一行通常用于关闭自定义弹窗或模态控制器。在你的场景中,如果“狠心退出”按钮位于一个由this.controller管理的自定义确认弹窗内,那么这行代码是合理的,用于先关闭这个二次确认弹窗。如果按钮就在主页面,这行代码可能无效或引发错误,应移除。

  2. 核心退出方法(this.getUIContext().getHostContext() as common.UIAbilityContext)?.terminateSelf(); 是标准的应用退出方式。它用于终止当前的UIAbility(应用组件实例),是HarmonyOS Next中关闭应用前台的推荐做法。

优化后的建议代码: 假设你的按钮位于一个自定义弹窗(由this.controller控制)内,代码应如下,逻辑更清晰:

Button('狠心退出')
    .type(ButtonType.Capsule)
    .fontColor(Color.White)
    .fontSize(25)
    .backgroundColor(Color.Transparent)
    .onClick(() => {
        // 1. 首先关闭当前的确认弹窗
        this.controller.close();
        // 2. 然后终止当前UIAbility,退出应用
        (this.getUIContext().getHostContext() as common.UIAbilityContext)?.terminateSelf();
    })

隐患排查与实现建议

  • 数据持久化:在调用terminateSelf()前,务必确保所有关键的用户数据(如游戏进度、设置等)已经保存到持久化存储(如Preferences或数据库)中。terminateSelf()会立即销毁Ability,不会等待异步操作。
  • 资源释放:虽然系统会回收资源,但良好的实践是,在Ability的onWindowStageDestroy()生命周期回调中,主动释放你持有的自定义资源(如传感器、锁等)。
  • 后台任务:如果你的应用有在后台运行的任务(如Service Ability、后台代理),需要根据业务逻辑决定是否在退出前台时一并停止。terminateSelf()仅终止当前UIAbility,不影响其他已启动的Ability。
  • 替代方案:对于简单的应用,直接调用terminateSelf()是标准做法。如果你的应用结构复杂,或者需要在退出前执行一系列清理工作,可以考虑将清理逻辑封装在Ability的onBackPress()生命周期中,但用户触发退出的路径更推荐你当前使用的明确按钮方式。

总结:你的实现方式主体正确,重点是确保在退出前完成数据保存,并理清controller.close()在你的上下文中的必要性。

回到顶部