点击PC端应用右上角的X按钮（关闭按钮），确认关闭前的回调处理事件
=================================

#### 问题现象

HarmonyOS PC端应用右上角的X按钮（关闭按钮）点击关闭之前增加一个二次确认弹窗，这个X按钮的点击事件在哪里添加呢？

#### 背景知识

[onPrepareToTerminate](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-uiability#onpreparetoterminate10)当UIAbility即将关闭前，系统触发该回调，用于在UIAbility正式关闭前执行其他操作。开发者可以在该回调中返回true阻拦此次关闭，然后在合适时机主动调用[terminateSelf](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#terminateself)接口关闭。例如，询问用户是否确认关闭UIAbility，再主动销毁UIAbility。

*   回调前提：该接口仅在2in1设备上生效，且需要应用申请[ohos.permission.PREPARE\_APP\_TERMINATE](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-for-all#ohospermissionprepare_app_terminate)权限。
*   回调时机：当用户通过点击应用窗口右上角的关闭按钮、或者通过Dock栏/托盘右键退出应用时，可以使用该回调。
*   从API version 15开始，当[UIAbility.onPrepareToTerminateAsync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-uiability#onpreparetoterminateasync15)实现时，本回调函数将不执行。当[AbilityStage.onPrepareTerminationAsync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-abilitystage#onprepareterminationasync15)或[AbilityStage.onPrepareTermination](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-abilitystage#onpreparetermination15)实现时，在Dock栏或系统托盘处右键点击关闭，本回调函数将不执行。
*   如果应用本身或者所使用的三方框架注册了[window.WindowStage.on('windowStageClose')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#onwindowstageclose14)监听，本回调函数将不执行。

#### 解决方案

[onPrepareToTerminate](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-uiability#onpreparetoterminate10)当UIAbility即将关闭前，系统触发该回调，用于在UIAbility正式关闭前执行其他操作。开发者可以在该回调中返回true阻拦此次关闭，然后在合适时机主动调用[terminateSelf](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#terminateself)接口关闭。该接口仅在2in1设备上生效，且需要应用申请ohos.permission.PREPARE\_APP\_TERMINATE权限。

具体实现请参考如下代码：

*   在module.json5配置文件中声明[ohos.permission.PREPARE\_APP\_TERMINATE](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-for-all#ohospermissionprepare_app_terminate)权限。
*   EntryAbility.ets文件中添加onPrepareToTerminate回调事件，代码如下所示：
    
    import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    import { window } from '@kit.ArkUI';
    
    
    
    
    const DOMAIN = 0x0000;
    
    
    
    
    export default class EntryAbility extends UIAbility {
     _ //当前window对象_
      private currentWindowStage: window.WindowStage | null = null;
    
    
      onCreate(): void {
        this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR\_MODE\_NOT\_SET);
    
    
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
      }
    
    
      onDestroy(): void {
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
      }
    
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
       _ // Main window is created, set main page for this ability_
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    
    
        if (this.currentWindowStage === null) {
          this.currentWindowStage = windowStage;
        }
        windowStage.loadContent('pages/Index', (err) => {
          if (err.code) {
            hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
            return;
          }
          hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
        });
    
    
      }
    
    
      onWindowStageDestroy(): void {
       _ // Main window is destroyed, release UI related resources_
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
      }
    
    
      onForeground(): void {
       _ // Ability has brought to foreground_
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
      }
    
    
      onBackground(): void {
       _ // Ability has back to background_
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
      }
    
    
      onPrepareToTerminate(): boolean {
        _// 开发者定义预关闭动作_
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onPrepareToTerminate');
       _ // 例如关闭应用之前弹窗提示是否关闭app_
        if (this.currentWindowStage !== null) {
          this.currentWindowStage?.getMainWindowSync().getUIContext().getPromptAction().showDialog({
            title: '提示',
            message: '确认是否关闭应用程序？',
            buttons: \[
              {
                text: '取消',
                color: '#0091FF'
              },
              {
                text: '确定',
                color: '#ff0000'
              }
            \]
          }).then(data => {
            if (data.index === 0) {
              this.currentWindowStage?.getMainWindowSync().getUIContext().getPromptAction().showToast({
                message: '已取消',
                duration: 2000
              });
            } else {
         _     // 确认关闭_
              this.context.terminateSelf();
            }
          });
        }
        return true; _// 已定义预关闭操作后，返回true表示UIAbility取消关闭_
      }
    };