HarmonyOS鸿蒙Next中设置"ohos.arkCompile.emptyBundleName": true如何运行不白屏

HarmonyOS鸿蒙Next中设置"ohos.arkCompile.emptyBundleName": true如何运行不白屏

import { hilog } from '@kit.PerformanceAnalysisKit'

const LogDomain = 0x0000;

@Entry
@Component
struct Index {
  @State message: string = '设置ohos.arkCompile.emptyBundleName参数为true'


  aboutToAppear(): void {
    let context = this.getUIContext().getHostContext();
    let fileName: string = 'demo_image.PNG'; // 需要替换为实际项目中的文件名
    // 获取文件内容
    // 确保在工程目录src/main/resources/rawfile里存在需要读取的文件
    context?.resourceManager.getRawFileContent(fileName, (error, value) => {
      if (error) {
        hilog.error(LogDomain, 'TestShow-', `error Code: ${error.code} error Msg: ${error.message}`);
        return;
      }
      // 这里读取到文件内容可以进行下一步操作
      let myBuffer: ArrayBufferLike = value.buffer;
      hilog.info(LogDomain, 'TestShow-', `buffer length: ${myBuffer.byteLength}`);
    });
  }


  build() {
    Column() {
      Text(this.message)

      // 使用 $r 引用资源
      Text($r('app.string.welcome_message'))
        .fontSize(30)
        .fontColor(Color.Blue)
        .margin({ top: 20 })

      // 使用 $r 引用图片资源
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
        .margin({ bottom: 20 })

      // 显示rawfile目录下的图片
      Image($rawfile('demo_image.PNG'))
        .width(150)
        .height(150)
    }
    .width('100%')
    .height('100%')
  }
}
在hvigor-config.json5设置了以下属性,运行会白屏
"properties": {
  "ohos.arkCompile.emptyBundleName": true
},

更多关于HarmonyOS鸿蒙Next中设置"ohos.arkCompile.emptyBundleName": true如何运行不白屏的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

尊敬的开发者,您好,此字段:ohos.arkCompile.emptyBundleName:仅支持在EntryAbility中使用loadContentByName加载首页,同时使用Navigation导航进行页面跳转时设置为true,否则会导致应用闪退。预览时暂不支持配置该字段,字段默认取值为false。
详细可以参考链接:properties
您可以在EntryAbility中使用loadContentByName加载首页,示例代码如下:

EntryAbility.ets

import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import * as Index from '../pages/Index'; // 导入命名路由页面

const DOMAIN = 0x0000;

export default class EntryAbility extends UIAbility {
  storage: LocalStorage = new LocalStorage();

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    try {
      this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
    } catch (err) {
      hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
    }
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    console.info('onWindowStageCreate');
    this.storage.setOrCreate('storageSimpleProp', 121);
    try {
      windowStage.loadContentByName(Index.entryName, this.storage, (err: BusinessError) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error(`Failed to load the content. Cause code: ${err.code}, message: ${err.message}`);
          return;
        }
        console.info('Succeeded in loading the content.');
      });
    } catch (exception) {
      console.error(`Failed to load the content. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }

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

Index.ets

import { hilog } from '@kit.PerformanceAnalysisKit'

const LogDomain = 0x0000;
export const entryName : string = 'Index';
@Entry({routeName: entryName})
// @Entry
@Component
export struct Index {
  @State message: string = '设置ohos.arkCompile.emptyBundleName参数为true'


  aboutToAppear(): void {
    let context = this.getUIContext().getHostContext();
    let fileName: string = 'demo_image.PNG'; // 需要替换为实际项目中的文件名
    // 获取文件内容
    // 确保在工程目录src/main/resources/rawfile里存在需要读取的文件
    context?.resourceManager.getRawFileContent(fileName, (error, value) => {
      if (error) {
        hilog.error(LogDomain, 'TestShow-', `error Code: ${error.code} error Msg: ${error.message}`);
        return;
      }
      // 这里读取到文件内容可以进行下一步操作
      let myBuffer: ArrayBufferLike = value.buffer;
      hilog.info(LogDomain, 'TestShow-', `buffer length: ${myBuffer.byteLength}`);
    });
  }


  build() {
    Column() {
      Text(this.message)

      // 使用 $r 引用资源
      Text($r('app.string.app_name'))
        .fontSize(30)
        .fontColor(Color.Blue)
        .margin({ top: 20 })

      // 使用 $r 引用图片资源
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
        .margin({ bottom: 20 })

      // 显示rawfile目录下的图片
      Image($rawfile('startIcon.png'))
        .width(150)
        .height(150)
    }
    .width('100%')
    .height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中设置"ohos.arkCompile.emptyBundleName": true如何运行不白屏的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这个问题大概率不是 UI 白屏,而是你开启了:

"ohos.arkCompile.emptyBundleName": true

之后,应用资源访问机制发生了变化

你的代码里用了:

$r('app.string.welcome_message')
$r('app.media.startIcon')
$rawfile('demo_image.PNG')

以及:

context.resourceManager.getRawFileContent(...)

这些都依赖应用的 bundleName 和资源索引。

emptyBundleName=true 的作用本身就是让编译产物不携带 bundleName 信息,主要用于 SDK、HAR、共享库等场景,不适合普通应用直接开启。开启后部分资源定位可能失效,从而导致页面启动异常甚至白屏。

从你的代码看,最值得怀疑的是:

Text($r('app.string.welcome_message'))
Image($r('app.media.startIcon'))
Image($rawfile('demo_image.PNG'))

因为这些都是编译期资源引用。

建议先做个最小验证:

build() {
  Column() {
    Text('Hello')
  }
}

然后开启:

"ohos.arkCompile.emptyBundleName": true

重新运行。

如果能显示:

Hello

说明白屏就是资源访问导致的。

如果连 Hello 都不显示,那就是当前工程本身不支持开启该参数。

我的经验是:

普通 HAP 应用
↓
不要开启 emptyBundleName

HAR/SDK开发
↓
才考虑开启 emptyBundleName

所以如果你的目标只是运行应用,这个参数建议直接关闭:

"ohos.arkCompile.emptyBundleName": false

或者删除这一项。

因为它本来就不是给普通应用页面运行场景准备的。

期待HarmonyOS能在未来推出更多针对企业用户的解决方案。

白屏,主要是因为你的 Index 页面中还使用了 $r(‘app.xxx’) 这类依赖普通包名的资源引用,它们在 emptyBundleName 模式下会直接导致页面构建失败(JS 报错),进而白屏。需要修改了 EntryAbility(使用 loadContentByName)和 Index.ets(改为命名路由)

组件/调用 空包名模式下是否可用 说明
$r(‘app.string.xxx’) ❌ 不可用 依赖 bundleName 定位资源表,空包名下路径非法
$r(‘app.media.xxx’) ❌ 不可用 同上
$rawfile(‘xxx’) ✅ 可用 通过 rawfile 相对路径加载,不依赖包名
getContext(this) ✅ 可用 全局函数,直接返回有效 Context
getUIContext().getHostContext() ⚠️ 可能异常 空包名下可能返回不完整 Context,建议不用

ohos.arkCompile.emptyBundleName:ArkTS编译转换后的产物,bundleName字段是否为空值。

  • true:bundleName字段的值是空值。
  • false(缺省默认值):bundleName字段是应用实际的包名。

在EntryAbility中使用 loadContentByName 加载首页,不能使用 loadContent。

// EntryAbility.ets
import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import * as Index from '../pages/Index'; // 导入命名路由页面
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...

  storage: LocalStorage = new LocalStorage();

  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    this.storage.setOrCreate('storageSimpleProp', 121);
    try {
      windowStage.loadContentByName(Index.entryName, this.storage, (err: BusinessError) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error(`Failed to load the content. Cause code: ${err.code}, message: ${err.message}`);
          return;
        }
        console.info('Succeeded in loading the content.');
      });
    } catch (exception) {
      console.error(`Failed to load the content. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }
};

改用上下文(Context)动态获取

你需要在组件加载时,通过 getContext(this) 明确拿到当前模块的 resourceManager 来动态加载资源,或者确保资源引用有上下文支撑。

你原来的这块

aboutToAppear(): void {
    let context = this.getUIContext().getHostContext();
    let fileName: string = 'demo_image.PNG'; // 需要替换为实际项目中的文件名
    // 获取文件内容
    // 确保在工程目录src/main/resources/rawfile里存在需要读取的文件
    context?.resourceManager.getRawFileContent(fileName, (error, value) => {
      if (error) {
        hilog.error(LogDomain, 'TestShow-', `error Code: ${error.code} error Msg: ${error.message}`);
        return;
      }
      // 这里读取到文件内容可以进行下一步操作
      let myBuffer: ArrayBufferLike = value.buffer;
      hilog.info(LogDomain, 'TestShow-', `buffer length: ${myBuffer.byteLength}`);
    });
  }

改成,

aboutToAppear(): void {
    // 显式传入当前组件实例获取 Context
    let context = getContext(this); 
    
    let fileName: string = 'demo_image.PNG';
    
    // 使用明确的 context 避免 getUIContext().getHostContext() 在空包名下失效
    context.resourceManager.getRawFileContent(fileName, (error, value) => {
      if (error) {
        hilog.error(0x0000, 'TestShow-', `error Code: ${error.code} error Msg: ${error.message}`);
        return;
      }
      let myBuffer: ArrayBufferLike = value.buffer;
      hilog.info(0x0000, 'TestShow-', `buffer length: ${myBuffer.byteLength}`);
    });
  }

这样是不是行

还是不行,这个值设置不了就算了

清缓存了吗,

尊敬的开发者,您好,您可以看下3楼的回复,如果有任何问题,您可以随时反馈

在HarmonyOS Next中设置"ohos.arkCompile.emptyBundleName": true后,应用白屏通常是因为未正确配置module.json5中的bundleName或资源路径错误。请检查module.json5确保bundleName非空且与AppScope/app.json5中的bundleName一致;同时确认pages配置路径正确,abilitieslaunchTypesingleton。重新编译并清理构建缓存即可。

设置 "ohos.arkCompile.emptyBundleName": true 后,应用 bundleName 被置空,导致 $r$rawfile 等资源引用路径失效(资源路径依赖 bundleName 作为作用域),运行时无法加载资源,页面渲染异常,出现白屏。

解决方式:在代码中避免使用 $r('app.xxx')$rawfile 等基于 bundleName 的资源引用,改为使用无需 bundleName 的动态加载方式,例如通过 resourceManager.getRawFileContent 获取 rawfile 内容,图片可先读取为 ArrayBuffer 再用 Image 组件的 pixelMap 接口显示。字符串资源可直接在代码中硬编码或从其他位置读取,不再依赖 $r

简单来说:弃用所有 $r$rawfile 语法,手动通过 resourceManager API 加载资源,即可避免白屏。

回到顶部