HarmonyOS开发:探索动态共享包的依赖与使用

举报
二流小码农 发表于 2023/08/31 17:06:43 2023/08/31
【摘要】 还是那句话,如果说,仅用于应用内部代码、资源的共享,建议使用动态共享包,如果想作为应用模块的依赖项被引用,就可以选择静态共享包。

前言


所谓共享包,和Android中的Library本质是一样的,目的是为了实现代码和资源的共享,在HarmonyOS中,给开发者提供了两种共享包,HAR(Harmony Archive)静态共享包,和HSP(Harmony Shared Package)动态共享包。


两者的区别是,HAR静态共享包中的代码和资源跟随使用方编译,如果有多个使用方,它们的编译产物中会存在多份相同拷贝;而HSP动态共享包中的代码和资源可以独立编译,运行时在一个进程中代码也只会存在一份,如下图所示:



之所以会出现HSP动态共享包,目的主要解决如下问题:

1、多个HAP引用相同的HAR,导致的APP包大小膨胀问题。

2、多个HAP引用相同的HAR,HAR中的一些状态变量无法共享的问题。


如果说,仅用于应用内部代码、资源的共享,建议使用动态共享包,如果想作为应用模块的依赖项被引用,就可以选择静态共享包,在之后得开发中,大家可以根据实际的业务需求进行选择性使用。


本章的内容大致如下:


1、如何创建一个共享包

2、动态共享包(library)手动依赖

3、动态共享包用命令方式依赖

4、动态共享包多种方式调用

5、动态共享包注意事项

6、总结


一、如何创建一个共享包


在当前工程项目名,右键,选择New,然后选择Module即可,这里我在Demo工程里进行创建,具体如何创建工程项目,这里就不赘述了,前边已经讲述过了,毕竟太简单了。



默认的有两种共享包模板,一种是动态共享包,一种是静态共享包,如下图。



设置共享包名字,点击Finish。


动态共享包创建完毕之后,结构如下图,其type类型为shared,如果你创建的是静态共享包,这里的类型就是har



二、动态共享包(library)手动依赖


经过第一步的操作,我们已经在Demo工程中,创建了一个动态共享包,如下图所示,目前有主Module,entry动态共享包sharelibrary。



entry如果想要调用sharelibrary中的代码或资源,那么必须让entry关联上sharelibrary,关联方式和Android中类似。


1、依赖方式一


entry中的oh-package.json5文件中,在dependencies中引入共享包sharelibrary,记住格式:

【"folder": "file:../folder"】,后面的folder就是你自己创建的共享包,至于前边的folder,是用来生成的映射目录,名字可以和共享包名字一致,也可以不一致。



引入之后,进行同步项目,点击Sync Now即可,当然了你可以可以,将鼠标放置在报错处会出现提示,在提示框中点击Run 'ohpm install'。



执行以上功能之后,就会映射到主Module,entryoh_modules目录下:



2、依赖方式二


除了依赖方式一之外,也可以采取如下的依赖方式,也就是【"@xx/xx": "file:../sharelibrary"】的方式,也是可以的,其原理和依赖方式一的格式一样,区别就是,会在oh_modules目录中创建一个@xx目录。



按照如上方式执行之后,会发现,已在oh_modules中,新建了一个”@ohos目录“,里面是映射的共享包。



三、动态共享包用命令方式依赖


上述,我们通过手动更改oh-package.json5文件完成了共享包的依赖,除了手动之外,我们也可以动过命令的方式进行实现,命令行中或在IDE Terminal窗口中,目录进入到主模块下,执行ohpm install ../folder命令即可,folder是你的共享包,如下图所示:



命令执行完毕之后,就会自动的在oh-package.json5里添加依赖,并生成映射文件。



四、动态共享包多种方式调用


1、方法调用


上述创建的共享包sharelibrary中,有一个工具类Calc,里面有一个简单的求和方法add,那么在entry中如何调用sharelibrary中的add方法呢?



其实很是简单,和Android项目一样,引入library之后,你可以调用共享包中的资源或者代码了,比如我们实现调用add方法,如下:



需要注意得是导包,正常情况下,当你打出add方法,会有提示导包,直接确认导包即可,如果没有,可以手动进行导包,导包得路径和你映射的地址基本上是一一对应的,比如,你采用的是@xx/xx的方式,导包就如下:



上面的案例是一个很简单的调用,给文字设置点击事件,直接调用共享包sharelibrary中,工具类Calc中的add方法。


目前貌似一切都没有问题,毕竟方法一切调用正常,我们直接运行至模拟器中查看,当然了,你也可以直接运行至HarmonyOS手机上,结果发现报错了,如下所示:



报错的原因就是,我们未执行部署多个包,毕竟我们在主模块后又创建了一个共享包,解决如下:


选择运行模块,点击Edit Configurations:



选择Deploy Multi Hap标签页,勾选Deploy Multi Hap Packages,选择我们的共享包即可:



再次运行,就可以运行正常了:



我们点击文字之后,就可以再控制台查看到,调用add求和方法之后的值了:



2、类的调用


上面的案例是如何调用共享包中的方法,那么共享包如果有一个工具类,我们该如何调用呢?


定义要外露的工具类,这里我简单的创建了一个日志工具类,记住需要用export关键字进行对外暴露。



使用和上述的方法流程一致,由于设置的是静态的方法,直接调用即可:




3、组件的调用


组件的调用和类的调用是一致的,如下,我定义了一个简单的文本组件,记住使用export关键字,进行对外暴露。


@Component
export struct TextWidget {
  @State message: string = '我是一个测试的文本'

  build() {
    Text(this.message)
      .fontSize(20)
      .fontWeight(FontWeight.Bold)
  }
}


使用方式如下,就可以把TextWidget作为一个组件进行调用。


import { add, Log ,TextWidget} from "sharelibrary"

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        TextWidget()
        Text($r('app.string.app_name'))
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            var number = add(100, 100)
            Log.log("求和", ""+number)
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}


4、跳转共享包内的页面


目前共享包中已经有了一个页面Index,为了便于区别,我们把里面的展示内容改为:“Hello sharelibrary”



在entry模块中,我们就可以如下进行跳转,url格式为:'@bundle:包名/模块名/路径/页面所在的文件名(不加.ets后缀)',具体跳转如下:


 router.pushUrl({
              url: '@bundle:com.example.demo/sharelibrary/ets/pages/Index'
            }).then(() => {
              console.log("push page success");
            }).catch(err => {
              console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`);
            })


具体效果如下:




5、如何使用共享包中的资源


既然作为一个共享包,要给到其他模块共用,除了代码上复用之外,剩下的就是资源了,查了很多资料和文档,怎么把resources暴露出去,这可难住了,可以很负责任的告诉大家,HarmonyOS目前还不支持,这一点和Android中Library还是有很大的区别,那怎么实现呢?


实现起来也是非常的简单,既然资源不能暴露,类和方法是可以暴露的啊,也就是大家可以把资源中的属性,通过工具类做一层中转即可。


1、定义资源


在共享包中我定义了一个很简单的字符串资源,当然了你也可以定义其他类型的资源,比如数字,图片,音视频等等。



2、定义工具类


工具类需要注意,结尾是ets类型,这是为了可以拿到Resource。



3、调用


导包后直接调用即可。



五、动态共享包注意事项


对外暴露的接口,需要在共享包入口文件index.ets中声明,否则,其他模块无法调用,都是固定的模式,比如上述的add方法,和自定义的组件等,切记!!!


同一个类中的,如果多个方法,可以复用,比如:


export { Log, add, minus } from './utils/test'

如果无法运行,报如下错误,请返回第四小节中的方法调用小节,查看完整的解决方式。



六、总结


还是那句话,如果说,仅用于应用内部代码、资源的共享,建议使用动态共享包,如果想作为应用模块的依赖项被引用,就可以选择静态共享包

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。