HarmonyOS 鸿蒙Next中主动捕获崩溃异常无效

HarmonyOS 鸿蒙Next中主动捕获崩溃异常无效

Button("try import").onClick(() => {
        try {
                const lib = "@bundle:com.huawei.hmos.crash/dead";
                import(lib).then((ns: ESObject) => {
                        
                }).catch((err: BusinessError) => {
                        console.error(err.message);
                })
        } catch (err) {
                console.error(err.message);
        }
})

errorManager、hiAppEvent都用了,还是直接崩溃,真崩溃。

有哪位大佬知道怎么做避免崩溃吗?谢谢答复。

按道理来说,即使模块不存在,也不应该直接崩溃啊,应该在catch里返回异常信息才对啊。


更多关于HarmonyOS 鸿蒙Next中主动捕获崩溃异常无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

12 回复

开发者您好,通过变量形式动态引入模块式,@bundle为非法入参形式,该场景下如果引入模块不存在时会导致crash,建议参考文档使用正确的入参形式:动态import变量表达式。 例如需要动态引入系统api,可以参考如下形式:

// HAP's src/main/ets/pages/Index.ets
let packageName = '@system.app';
import(packageName).then((ns:ESObject) => { ns.default.terminate(); });
packageName = '@system.router';
import(packageName).then((ns:ESObject) => { ns.default.clear(); });
packageName = '@ohos.curves';
import(packageName).then((ns:ESObject) => { ns.default.springMotion(0.555, 0.75, 0.001); });
packageName = '@ohos.matrix4';
import(packageName).then((ns:ESObject) => { ns.default.identity(); });
packageName = '@ohos.hilog';
import(packageName).then((ns:ESObject) => { ns.default.info(0x0000, 'testTag', '%{public}s', 'DynamicImport @ohos.hilog.'); });

完整示例如下:

import { BusinessError } from '@kit.BasicServicesKit';
import { camera } from '@kit.CameraKit';

@Entry
@Component
struct Index {
  // 非法入参会导致找不到模块式直接crash
  private libErrName: string = '[@bundle](/user/bundle):com.huawei.hmos.crash/dead';
  private libName: string = '@ohos.multimedia.camera';

  build () {
    Column () {
      // 通过动态引入方式使用模拟器不支持的kit,不会crash而是抛出异常
      Button ('动态调用')
        .onClick (() => {
          import (this.libName).then ((ns: ESObject) => {
            let cameraManager: camera.CameraManager =
              ns.default.getCameraManager (this.getUIContext ().getHostContext ());
            let mode = cameraManager.getTorchMode ();
            mode = mode == camera.TorchMode.ON ? camera.TorchMode.OFF : camera.TorchMode.ON;
            cameraManager.setTorchMode (mode);
          }).catch ((err: BusinessError) => {
            console.error (`${err.message}`);
            // 进入catch,打印import failed
            console.error ('import failed');
          });
        })
        .margin ({
          bottom: 20
        });

      // 静态引入模拟器不支持的kit,会导致crash
      Button ('打开手电筒')
        .onClick (() => {
          let cameraManager = camera.getCameraManager (this.getUIContext ().getHostContext ());
          let mode = cameraManager.getTorchMode ();
          mode = mode == camera.TorchMode.ON ? camera.TorchMode.OFF : camera.TorchMode.ON;
          cameraManager.setTorchMode (mode);
        });
    }
    .height ('100%')
    .width ('100%')
    .justifyContent (FlexAlign.Center);
  }
}

更多关于HarmonyOS 鸿蒙Next中主动捕获崩溃异常无效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我项目中有一个页面用到了FunctionComponent 组件,真机运行没有问题,运行到模拟器就崩溃了。所以我想判断一下,该设备是否支持FunctionComponent 组件。怎么判断呢,我是这样做的,import成功就是支持,失败就不支持,但是呢,import直接崩溃了。假设这个’@bundle:com.huawei.hmos.crash/dead’在真机存在,import没有问题,但是在模拟器不存在,就崩溃了,而不是catch异常,明白我的意思了吧。你不能说import的模块一定要存在啊,因为有的设备就是不支持不存在。

开发者您好,通过变量名动态引入不存在的模块,通过catch可以捕获异常,

示例代码如下:

import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct DynamicImportDemo {
  @State message: string = 'Hello World';
  private libName: string = '@bundle:com.huawei.hmos.crash/dead';
  //不存在的包名
  private libName1: string = 'libhar';
  build () {
    Column () {
      Text (this.message);
      Button ('动态调用')
        .onClick (() => {
          import (this.libName1).then ((ns: ESObject) => {
            console.info ('import success');
          }).catch ((err: BusinessError) => {
            console.info (`${JSON.stringify (err)}`);
            //进入catch,打印import failed
            console.info ('import failed');
          });
        })
        .margin ({
          bottom: 20
        });
    }
    .height ('100%')
    .width ('100%')
    .justifyContent (FlexAlign.Center);
  }
}

具体想询问您如下信息: 1、此包名从什么路径引入的呢,具体是怎么形成这个包名呢? 2、引入这个模块是为了实现什么功能?

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17,

有的模块模拟器是不支持的,在模拟器打开到这个页面立马崩溃,所以需要动态引入,导入成功就加载该功能,导入失败说明是模拟器或者设备不支持,就不加载该功能了。现在的问题是,import直接崩溃了,都无法判断了。感觉是import的bug。

就比如FunctionComponent 组件,某个页面用了这个组件,不管是否加载到树上,运行到模拟器打开这个页面直接崩溃。

开发者您好,import可以传入常量,

例如:

import('./xx').then((ns:ESObject) => {
  console.info('successed');
});

如果想要跨模块引入:

HAP常量动态import HSP模块名

// HSP's Index.ets
export function add(a: number, b: number): number {
  let c = a + b;
  console.info('DynamicImport I am a HSP, %d + %d = %d', a, b, c);
  return c;
}
// HAP's src/main/ets/pages/Index.ets
import('myhsp').then((ns:ESObject) => {
  console.info('DynamicImport ns.add(3, 5) = %d', ns.add(3, 5));
});
// HAP's oh-package.json5
"dependencies": {
  "myhsp": "file:../myhsp"
}

具体参考链接:动态加载-ArkTS模块化-ArkTS运行时-ArkTS(方舟编程语言)-应用框架 - 华为HarmonyOS开发者

如果还是不能解决您的问题,麻烦您提供下能复现问题的完整demo吧。

import变量是可以的,能不能导入是一回事,但是不要弄得整个APP直接崩溃啊。我给出的demo代码,点击button就崩溃。 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-dynamic-import#动态import变量表达式

加载其他模块或API都会走catch 你的这个路径就会崩溃。。

是的,在taskpool子线程中运行也一样崩溃。。。,

在HarmonyOS Next中,主动捕获崩溃异常无效通常与系统设计有关。鸿蒙Next的崩溃处理机制可能限制了应用层对某些系统级异常的捕获。异常捕获代码(如ErrorManagerprocess相关API)可能无法拦截由系统框架或底层运行时触发的致命错误。请检查崩溃日志,确认异常类型是否属于可捕获范围,并查阅官方API文档中关于异常处理的限制说明。

在HarmonyOS Next中,import() 是一个异步操作,其返回的是一个Promise。你提供的代码中,try-catch 块包裹的是发起异步导入的语句,而不是异步操作本身。当模块加载失败时,异常是在Promise的rejection中抛出的,外层的同步try-catch无法捕获到。

你的代码结构是正确的,已经在Promise的.catch方法中处理了错误。如果应用仍然崩溃,问题可能不在于异常未被捕获,而在于加载的模块"@bundle:com.huawei.hmos.crash/dead"本身可能包含了会导致应用崩溃的代码(例如,原生的严重错误),这种崩溃超出了ArkTS异常处理机制的能力范围。

关键点在于:

  1. 异步错误捕获:对于import(),必须使用Promise的.catch()方法或async/await配合try-catch来捕获错误。你代码中的.catch部分已经做到了这一点。
  2. 崩溃与异常:ArkTS/JavaScript的try-catch和Promise错误处理主要捕获的是可恢复的运行时异常。如果导入的Native模块(C/C++代码)内部发生了内存访问违规等严重错误,这会直接导致进程崩溃,属于不可恢复的错误,应用层的异常处理机制无法拦截这种崩溃。

建议检查方向:

  • 确认 "@bundle:com.huawei.hmos.crash/dead" 这个模块的具体实现。如果它是一个故意触发崩溃的测试模块,那么其设计目的就是导致应用崩溃,异常处理是无效的。
  • 如果这是你自定义的模块,请检查该Native模块的代码是否存在内存越界、空指针访问等致命问题。
  • 确保你的开发环境、SDK和工具链是最新版本。

总结:你的异步错误捕获代码逻辑本身没有原则性问题。应用仍然崩溃,强烈表明是所加载的Native模块内部存在致命缺陷,引发了进程级崩溃,这超出了ArkTS异常处理的范畴。你需要检查该模块本身的代码。

回到顶部