目录

如何实现资源替换overlay机制

问题现象

HarmonyOS如何实现资源替换的静态overlay以及动态overlay?

背景知识

解决方案

  

动态overlay

静态overlay

overlay资源包类型

HAP/HSP

HSP

核心API

ResourceManager.addResource/removeResource

overlay.setOverlayEnabled

应用场景

静态资源定制(多语言、主题)。

动态UI交互(导航菜单、浮动面板)。

  1. 利用静态overlay机制实现资源替换:
    1. 主应用EntryAbility中使能静态overlay:
      // EntryAbility.ets文件
      onCreate(): void {
        this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
        // 系统默认使能,这里可以不设置
        overlay.setOverlayEnabled('staticOverlay', true, (err) => {
          if (err) {
            hilog.error(DOMAIN, 'testTag', 'err code: ' + err.code + ' ' + 'message:' + err.message);
            return;
          }
          console.info('setOverlayEnabled success');
        });
      }
    2. 主应用Index页面中使用Resource目录下的“bg.png”文件:
      // Index.ets
      @Entry
      @Component
      struct Index {
      
        build() {
          RelativeContainer() {
            Image($r('app.media.bg'))
              .width(100)
              .height(100)
              .alignRules({
                center: { anchor: '__container__', align: VerticalAlign.Center },
                middle: { anchor: '__container__', align: HorizontalAlign.Center }
              })
          }
          .height('100%')
          .width('100%')
        }
      }

    3. 创建静态overlay资源包staticOverlay.hsp,Resource目录中也有“bg.png”文件,路径和entry相同:
      • 使用DevEco Studio创建HSP模块,和正常创建HSP步骤一致,不再赘述。

      • staticOverlay.hsp中module.json5配置:

        targetModuleName和targetPriority标签需要单独设置。

        targetModuleName:字符串类型,指定要overlay的应用中的目标moduleName,这里需要替换Entry的资源,所以设置为Entry的moduleName。

        targetPriority:整数类型,指定overlay优先级。

        // staticOverlay module.json5
        {
          "module": {
            "name": "staticOverlay",
            "type": "shared",
            "description": "$string:shared_desc",
            "deviceTypes": [
              "phone"
            ],
            "deliveryWithInstall": true,
            "pages": "$profile:main_pages",
            "targetModuleName": "entry",
            "targetPriority": 1
          }
        }
    4. 编译静态overlay资源包staticOverlay.hsp:

      由于静态overlay需要替换实现主Entry包中的资源,所以需要注意的是,要在DevEco Studio上Run->Edit Configurations中选中entry包进行勾选“Deploy Multi Hap/Hsp Packages”选项,打包编译时会将静态资源包编译到应用HAP中:

      执行编译后,在静态资源包这里会看到编译生成了编译产物:

    5. 最终,应用安装后的效果为:

      staticOverlay包中“bg.png”资源替换了entry包中的“bg.png”,资源文件的路径、名称要和被替换包中资源文件一致。

  2. 利用动态overlay机制实现资源替换:
    1. 主应用Index页面中使用Resource目录下的“bg.png”文件:
      // Index1.ets
      import { common } from '@kit.AbilityKit';
      
      @Entry
      @Component
      struct Index1 {
        context: common.Context = this.getUIContext().getHostContext() as common.Context;
        @State image: PixelMap = this.context.resourceManager.getDrawableDescriptor($r('app.media.bg').id).getPixelMap();
      
        build() {
          RelativeContainer() {
            Image(this.image)
              .width(100)
              .height(100)
              .alignRules({
                center: { anchor: '__container__', align: VerticalAlign.Center },
                middle: { anchor: '__container__', align: HorizontalAlign.Center }
              }).onClick(()=> {
                let path = this.context.bundleCodeDir + '/dynamicOverlay.hsp';
                try {
                  this.context.resourceManager.addResource(path);
                  this.image = this.context.resourceManager.getDrawableDescriptor($r('app.media.bg').id).getPixelMap();
                } catch (error) {
                  let code: number = (error as BusinessError<number>).code;
                  let message: string = (error as BusinessError<string>).message;
                  console.error(`addResource failed, error code: ${code}, message: ${message}.`);
                }
            })
          }
          .height('100%')
          .width('100%')
        }
      }

    2. 创建动态overlay资源包dynamicOverlay.hsp,Resource目录中也有“bg.png”文件,路径和entry相同:
      • 使用DevEco Studio创建HSP,和正常创建HSP步骤一致,不再赘述。

      • dynamicOverlay.hsp中module.json5配置:(动态overlay不需要配置targetModuleName和targetPriority标签)。
        // dynamicOverlay module.json5
        {
          "module": {
            "name": "dynamicOverlay",
            "type": "shared",
            "description": "$string:shared_desc",
            "deviceTypes": [
              "phone"
            ],
            "deliveryWithInstall": true,
            "pages": "$profile:main_pages"
          }
        }
    3. 编译动态overlay资源包dynamicOverlay.hsp,和上述静态overlay资源包编译步骤一致,不再赘述。
    4. 应用安装后,点击图标运行效果预览: