退出应用时的动画效果异常
============

#### 问题现象

退出应用时，退出动效像闪退一样，而非由大变小的退出动画效果。

#### 背景知识

1.  [killAllProcesses](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-applicationcontext#applicationcontextkillallprocesses)：终止应用的所有进程，进程退出时不会正常走完应用生命周期。使用Promise异步回调。仅支持主线程调用。
2.  [terminateSelf](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#terminateself)：停止Ability自身，使用callback异步回调。
3.  [自定义组件的生命周期](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-custom-component-lifecycle)，即被@Entry装饰的组件生命周期，提供[onBackPress](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-custom-component-lifecycle#onbackpress)生命周期接口，当用户点击返回按钮或执行侧滑操作时触发。
4.  [ProcessManager](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-process#processmanager9)：提供用于新增进程的抛异常接口。
5.  [exit](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-process#exit9)：终止程序。请谨慎使用此接口，此接口调用后应用会退出。

#### 问题定位

1.  排查应用的退出方式，直接采用killAllProcesses()方法会导致应用退出时动效异常。
    
    import { UIAbility } from '@kit.AbilityKit';
    
    export default class MyAbility extends UIAbility {
      onBackground() {
        let applicationContext = this.context.getApplicationContext();
        applicationContext.killAllProcesses();
      }
    }
    
2.  排查应用是否重写了onBackPress()方法，若应用在onBackPress()方法中采用同步退出方式会造成退出动效异常。
    
    @Entry
    @Component
    struct IndexComponent {
      @State textColor: Color = Color.Black;
    
      onBackPress() {
        new process.ProcessManager().exit(0);
        return true;
      }
    
      build() {
        Column() {
          Text('Hello World')
            .fontColor(this.textColor)
            .fontSize(30)
            .margin(30)
        }.width('100%')
      }
    }
    

#### 分析结论

1.  killAllProcesses()方法会杀死应用所在的整个进程，立即结束应用的所有活动。这种退出方式无动画过渡，会造成退出时像闪退一样的动效异常。
2.  应用重写了onBackPress()方法，但在onBackPress()方法中采用同步退出方式，造成退出时像闪退一样的动效异常。

#### 修改建议

修改应用退出方式，建议使用terminateSelf()这种退出方式，它用于停止当前Ability自身，提供了动画过渡，用户体验较好。

import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct IndexComponent {
  @State textColor: Color = Color.Black;
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;

  onPageShow() {
    this.textColor = Color.Blue;
    console.info('IndexComponent onPageShow');
  }

  onPageHide() {
    this.textColor = Color.Transparent;
    console.info('IndexComponent onPageHide');
  }

  onBackPress() {
    this.textColor = Color.Red;
    console.info('IndexComponent onBackPress');
    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');
    });
  }

  build() {
    Column() {
      Text('Hello World')
        .fontColor(this.textColor)
        .fontSize(30)
        .margin(30)
    }.width('100%')
  }
}