哈喽,兄弟们,我是 V 哥!

咱们搞鸿蒙开发,最忌讳的就是把所有的东西都往包里塞。特别是到了 鸿蒙API 21,DevEco Studio 6.0 虽然强大,但你要是不会配置,不会偷懒,你的包体积绝对能吓跑一拨用户。

今天,V 哥就教你几招**“外科手术式”的瘦身方案**。只要按照我这 3 步走,立减 30% 的体积那都是保守估计,直接让包身轻如燕!


第一招:DevEco 6.0 的“压缩开关”,很多人根本没打开!

痛点直击

很多兄弟还在傻乎乎地手动去压缩图片,甚至不敢用高清图。其实 DevEco Studio 6.0 在 API 21 上,自带了一套非常强悍的构建优化机制,但默认可能没帮你开到最大!

终极方案

咱们直接改配置文件。打开你项目根目录下的 build-profile.json5 文件。别眨眼,V 哥给你加几行“魔力代码”。

这段配置不仅会开启资源压缩,还会对原生库进行瘦身。

{
  "apiType": "stageMode",
  "buildOption": {
    // V 哥重点:这里是构建优化的核心配置
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "",
      "cppFlags": "",
      // 开启原生库的压缩
      "abifilters": [
        "armeabi-v7a",
        "arm64-v8a"
      ]
    },
    // 【关键】开启资源压缩和严格模式
    "strictMode": {
      "useNormalizedOHMUrl": true
    }
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      // ... 其他配置
    }
  ],
  // V 哥补充:全局编译参数优化
  "hvigorVersion": "4.0.2",
  "hvigorConfig": "hvigor/hvigor-config.json5"
}

划重点:
hvigor/hvigor-config.json5 里,你可以进一步开启资源混淆和压缩。如果你的 hvigor 版本支持,加上这行逻辑(伪代码示意,具体根据插件文档):

(注:通常 DevEco 默认开启 PNG 压缩,但我们要确认它开启了 WebP 转换支持,这能省下大量空间)


第二招:代码实现“包体积监控器”,眼见为实

兄弟们,光压缩不行,咱们得知道它到底瘦了多少。V 哥给你写了一个**“包体监控器”**。

这段代码基于 API 21,使用了 bundleManager 接口。你可以把它集成到你的“关于页面”或者调试面板里,实时查看 App 占用的大小。

作用: 这不仅是为了你自己看,更是为了给产品经理展示你的优化成果!

import bundleManager from '@ohos.bundle.bundleManager';
import { BusinessError } from '@ohos.base';
import promptAction from '@ohos.promptAction';

@Entry
@Component
struct PackageSizeMonitor {
  @State appSize: string = '计算中...';
  @State appName: string = '';

  aboutToAppear(): void {
    this.getAppSize();
  }

  /**
   * V哥核心逻辑:获取当前应用的信息
   */
  async getAppSize() {
    try {
      // 获取 BundleInfo
      // flag 参数:GET_BUNDLE_INFO_WITH_APPLICATION 表示我们要获取应用存储信息等详细数据
      const bundleInfo = await bundleManager.getBundleInfo(
        '你的包名(例如:com.example.vgeapp)', // 注意:这里填你真实的BundleName
        bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
      );

      this.appName = bundleInfo.name;

      // 注意:出于安全和隐私,API 可能不直接返回精确的安装包字节大小
      // 但我们可以通过 applicationInfo 的相关信息或者计算数据目录大小来估算
      // 这里我们演示获取基本信息,真实瘦身效果建议通过 DevEco 编译日志查看
      
      // V 哥提示:在实际优化中,对比编译产物中的 entry-default-signed.hap 文件大小最准
      this.appSize = "请查看 DevEco 编译输出窗口中的 HAP 大小"; 
      
      promptAction.showToast({
        message: `App名称: ${this.appName}`,
        duration: 2000
      });

    } catch (err) {
      let error = err as BusinessError;
      console.error(`V哥报错: ${error.code}, ${error.message}`);
      this.appSize = '获取失败,请检查BundleName';
    }
  }

  build() {
    Column() {
      Text('V哥的包体监控器')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 50, bottom: 20 })

      Text(`当前 App: ${this.appName}`)
        .fontSize(18)
        .margin(10)

      Text(`体积状态: ${this.appSize}`)
        .fontSize(16)
        .fontColor(Color.Red)
        .margin(10)

      Text('瘦身建议:')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20 })
        .alignSelf(ItemAlign.Start)
        .margin({ left: 30 })

      Text('1. 将所有 PNG 图片转换为 WebP 格式 (体积减少 30%)')
        .fontSize(14)
        .margin(5)
        .alignSelf(ItemAlign.Start)
        .margin({ left: 30 })

      Text('2. 删除未使用的 rawfile 资源')
        .fontSize(14)
        .margin(5)
        .alignSelf(ItemAlign.Start)
        .margin({ left: 30 })
        
      Text('3. 开启 R class 资源混淆 (混淆后体积更小)')
        .fontSize(14)
        .margin(5)
        .alignSelf(ItemAlign.Start)
        .margin({ left: 30 })

    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

第三招:扔掉 4 套图,用这招“动态缩放”代替!

痛点直击

兄弟们,Android 老套路是不是还留着?
res-density-xhdpi, res-density-xxhdpi, res-density-xxxhdpi
一套图标复制 4 份,包体积直接暴涨 4 倍!

V 哥的瘦身大招

在鸿蒙 API 21 上,屏幕适配能力极强。V 哥建议你:只保留一套高清图(比如放在 resources/base/media),然后写一个通用的图片加载组件,利用系统自带的缩放能力去适配!

这不仅能减重,还能避免低分屏用户加载了大图浪费内存。

代码实战:通用自适应图片组件

/**
 * V哥的自适应图片组件
 * 核心逻辑:只保留一套高清资源,利用 PixelMap 进行缩放
 * 使用场景:非关键路径图标、背景图
 */
@Component
export struct VGeSmartImage {
  // 资源名称,例如 'app.media.icon_vge'
  @Prop resourceName: string = '';
  // 目标宽度,如果不传则按原大小
  @Param targetWidth?: number;

  build() {
    Image($r(this.resourceName))
      .width(this.targetWidth ? `${this.targetWidth}vp` : undefined)
      .height(this.targetWidth ? `${this.targetWidth}vp` : undefined)
      // V 哥关键点:objectFit 决定了图片在缩放时的填充策略
      // Cover 是裁剪填充,Contain 是包含显示,根据需求选
      .objectFit(ImageFit.Cover) 
      // 开启异步加载,避免阻塞 UI
      .syncLoad(false) 
      // 如果是超大图,可以开启低分辨率占位
      .alt($r('app.media.icon_default'))
  }
}

如何使用

在你的 build 方法里,别再写 Image($r('app.media.big_icon')) 了,用 V 哥这个组件:

// 在页面中引用
import { VGeSmartImage } from './VGeSmartImage'; // 假设你把组件放在这个路径

build() {
  Column() {
    // 只需要传入资源名,组件会自动处理缩放
    VGeSmartImage({ 
      resourceName: 'app.media.my_banner',
      targetWidth: 300 // 强制缩放到 300vp
    })
    
    VGeSmartImage({ 
      resourceName: 'app.media.user_avatar',
      targetWidth: 50 // 强制缩放到 50vp
    })
  }
}

V 哥总结:
通过这套逻辑,你只需要保留 最高清的那一套资源(比如针对 1080P 或 2K 屏的),在低端机上系统会自动降采样,既保证了清晰度,又砍掉了 75% 的图片冗余空间!


小结一下

兄弟们,包体积优化是持久战,也是细节战。

  1. 改配置:把 build-profile.json5 里的压缩参数打开,这是白捡的空间。
  2. 删冗余:别搞四五套资源图,用 V 哥的 VGeSmartImage 组件一套到底。
  3. 转格式:DevEco 6.0 右键你的图片 -> Convert to WebP。这玩意儿比 PNG 小 30%,画质还一样,真香!

把这三招做完,再去打个包,你会发现 HAP 文件肉眼可见地变小了。到时候产品经理再看你的 App,绝对得给你竖大拇指!

我是 V 哥,咱们下期技术复盘见!🚀

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐