目录

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

问题现象

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

背景知识

  1. killAllProcesses:终止应用的所有进程,进程退出时不会正常走完应用生命周期。使用Promise异步回调。仅支持主线程调用。
  2. terminateSelf:停止Ability自身,使用callback异步回调。
  3. 自定义组件的生命周期,即被@Entry装饰的组件生命周期,提供onBackPress生命周期接口,当用户点击返回按钮或执行侧滑操作时触发。
  4. ProcessManager:提供用于新增进程的抛异常接口。
  5. exit:终止程序。请谨慎使用此接口,此接口调用后应用会退出。

问题定位

  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%')
  }
}