鸿蒙系列--动态共享包的依赖与使用

news2024/11/20 4:56:35

一、前言

        HarmonyOS的共享包相当于Android的Library,在HarmonyOS中,给开发者提供了两种共享包,HAR(Harmony Archive)静态共享包,和HSP(Harmony Shared Package)动态共享包

区别:

  • 静态共享包中的代码和资源跟随使用方编译,如果有多个使用方,它们的编译产物中会存在多份相同拷贝
  • 动态共享包中的代码和资源可以独立编译,运行时在一个进程中代码也只会存在一份

动态共享包解决的问题:

  • 多个使用方引用相同的共享包,导致的APP包大小膨胀问题
  • 多个使用方引用相同的共享包,共享包中的一些状态变量无法共享的问题

两者的使用场景:

  • 仅用于应用内部代码、资源的共享,建议使用动态共享包
  • 作为应用模块的依赖项被引用,就可以选择静态共享包

二、共享包的创建

File -> New -> Module

有两种共享包,一种是一种是动态共享包Shared Library,一种是静态共享包Static Library

选择一种共享包,点击Next

设置共享包的name,点击Finish,即可完成共享包的创建

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

三、动态共享包添加依赖

动态共享包创建完成之后,有两个Module,主Module【entry】和动态共享包【Common】

如何在【entry】中调用【Common】模块中的代码和资源文件等,需要让【entry】关联依赖上【Common】

要使用HSP中的接口,首先需要在使用方的oh-package.json5中配置对它的依赖

1、依赖方式一

在【entry】中的oh-package.json5文件中,在dependencies中引入共享包【Common】

引入格式:

'folder': "file:../folder"

描述:

  • 后面的folder就是创建的共享包名称,比如这里的Common
  • 前面的folder是用来生成的映射目录,可与共享包名称,也可以自行定义

添加了之后需要同步项目,点击【Sync Now】即可,也可以点击提示信息下的【Run 'ohpm install'

同步之后,该模块就会被映射到Module【entry】的oh_modules目录下

2、依赖方式二

也可以使用@xx/xx来添加依赖

引入格式:

"@xx/xx": "file:../Common"   

比如:import { add } from '@ohos/Common'

同步之后会在oh_modules目录下创建ohos>Common

3、依赖方式三

        除了以上手动方式添加依赖之外,也可以使用命令的方式进行实现,命令行中或在IDE Terminal窗口中,目录进入到主模块下,执行ohpm install ../folder命令,folder是你的共享包

apple@lengfeng MyApplication % cd entry
apple@lengfeng entry % ohpm install ../Common

注意:需要提前配置ohpm

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

四、动态共享包调用方式

1.方法调用

在创建的共享包Common中,有一个自动创建一个工具类Calc,里面有一个求和方法add       

 使用的时候需要引入:

import { add } from 'common/src/main/ets/utils/Calc'

//或者第二种依赖方式导包

import { add } from '@ohos/Common'

使用如下:

import { add } from 'common/src/main/ets/utils/Calc'
//或者
//import { add } from '@ohos/Common'
//或者
//import { add } from 'common'


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

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            var result = add(1, 2)
            this.message = "result=" + result
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

案例中是给一个Text增加一个点击事件,然后调用【Common】中的Calc类的add方法,返回一个结果,并显示更新Text

预览是一片空白的,没关系,直接运行到模拟器,或者HarmonyOS手机上查看,没想到报错了

根据报错信息提示:未执行部署多个包,由于增加了一个【Common】共享包,解决方案是

选择上面运行模块,选择Edit Configurations

Deploy Multi Hap标签页,勾选Deploy Multi Hap Packages,然后选择新增的共享包即可,将entry和library模块一起运行

然后就能正常运行了

点击文本,就能看到计算后的结果了

2.类的调用

调用共享包中的工具类

在共享包中定义一个工具类Log.ts,需要用export关键字进行对外暴露

export class Log {
  static i(msg: string) {
    console.info(msg)
  }

  static e(msg: string) {
    console.error(msg)
  }
}

然后在【common】的Index添加导出Log,对外暴露的接口,需要在入口文件index.ets中声明

在【entry】中导入类,就可以直接使用了

import { add,Log } from 'common'

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

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            var result = add(1, 2)
            this.message = "result=" + result
            Log.i("----------------")
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

点击Text后打印出日志:

3.组件的调用

组件的调用跟类的调用一致

先export导出,然后import导入

@Component
export struct CommonText {
  @State message: string = '我是Common模块中的组件'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.Red)
      }
      .width('100%')
    }
  }
}

import { add, Log, CommonText } from 'common'

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

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            var result = add(1, 2)
            this.message = "result=" + result
            Log.info("----------------")
          })
        CommonText()
      }
      .width('100%')
    }
    .height('100%')
  }
}

效果图:

4.页面路由跳转

想在【entry】模块中,添加一个按钮跳转至【Common】模块中的CommonIndex页面(路径为:Common/src/main/ets/pages/CommonIndex.ets),那么可以在使用方的代码(entry模块下的Index.ets,路径为:entry/src/main/ets/pages/Index.ets)里这样使用:

import { add, Log, CommonText } from 'common'
import router from '@ohos.router'

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

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            var result = add(1, 2)
            this.message = "result=" + result
            Log.info("----------------")
          })
        CommonText()
          .onClick(() => {
            router.pushUrl({ url: '@bundle:com.lf.myapplication/Common/ets/pages/CommonIndex' })
              .then(() => {
                console.log("push page success");
              })
              .catch(err => {
                console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`);
              })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

其中router.pushUrl方法的入参中url的内容为:

'@bundle:com.lf.myapplication/Common/ets/pages/CommonIndex'

内容格式为:

'@bundle:包名(bundleName)/模块名(moduleName)/路径/页面所在的文件名(不加.ets后缀)'

包名的查看路径:

AppScope -> app.json5中可以查看app的信息,包括包名,版本code、name等

效果图:

点击 CommonText()组件跳转到【Common】模块中的CommonIndex页面

5.资源访问

创建资源目录:

选择模块名 > 右击 > New > Resource File

  • 可同时创建资源目录和资源文件,文件默认创建在base目录的对应资源组。如果选择了限定词,则会按照命名规范自动生成限定词和资源组目录,并将文件创建在限定词目录中
  • 图中File name为需要创建的文件名。Resource type为资源组类型,默认是element。Root Element为资源类型。Avaliable qualifiers为供选择的限定词目录,通过右边的小箭头可添加或者删除

创建资源文件

在资源目录(element、media、profile)的右键菜单选择“New > XXX Resource File”,即可创建对应资源组目录的资源文件。例如,在element目录下可新建Element Resource File

资源包内资源访问
  • 对于应用资源,在工程中,通过"$r('app.type.name')"形式引用。其中,app为应用内resources目录中定义的资源;type为资源类型或资源的存放位置,取值包含“color”、“float”、“string”、“plural”、“media”;name为资源命名,由开发者定义资源时确定

  • 对于rawfile目录资源,通过"$rawfile('filename')"形式引用。其中,filename为rawfile目录下文件的相对路径,文件名需要包含后缀,路径开头不可以以"/"开头

  • 对于rawfile目录的descriptor,可通过资源管理的getRawId接口引用,其返回值descriptor.fd为hap包的fd。此时,访问rawfile文件需要结合{fd, offset, length}一起使用

Text($r('app.string.string_hello'))
  .fontColor($r('app.color.color_hello'))
  .fontSize($r('app.float.font_hello'))


//引用string.json资源。Text中$r的第一个参数指定string资源,第二个参数用于替换string.json文件中的%s
//"这是原文本,可以拼接一个:%s"
Text($r('app.string.message_arrive', "拼接文本"))

// media资源的$r引用
Image($r('app.media.my_background_image'))  

// rawfile$r引用rawfile目录下图片
Image($rawfile('test.png'))                 

// rawfile$r引用rawfile目录下图片
Image($rawfile('newDir/newTest.png'))       

  • 对于系统资源,可以通过“$r('sys.type.resource_id')”的形式引用。其中,sys为系统资源;type为资源类型,取值包括“color”、“float”、“string”、“media”;resource_id为资源id
Text('Hello')
  .fontColor($r('sys.color.ohos_id_color_emphasize'))
  .fontSize($r('sys.float.ohos_id_text_size_headline1'))
  .fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
  .backgroundColor($r('sys.color.ohos_id_color_palette_aux1'))

Image($r('sys.media.ohos_app_icon'))
  .border({
    color: $r('sys.color.ohos_id_color_palette_aux1'),
    radius: $r('sys.float.ohos_id_corner_radius_button'), width: 2
  })
  .margin({
    top: $r('sys.float.ohos_id_elements_margin_horizontal_m'),
    bottom: $r('sys.float.ohos_id_elements_margin_horizontal_l')
  })
  .height(200)
  .width(300)
跨包访问资源

注意:HarmonyOS目前还不支持资源跨包调用

如果确实需要使用共享包中的资源,可以另辟蹊径。

既然资源不能暴露,但是类和方法可以暴露,也就是可以把资源中的属性,通过工具类做一层中转即可

1.定义资源

在【Common】中有一个字符串资源message_arrive,想要在【entry】中使用,如何实现呢?

2.定义工具类

定义一个工具类中转 StringUtil.ets,就可以拿到对应的资源文件了

export class StringUtil {
  static getArriveMessage(): Resource {
    return $r('app.string.message_arrive')
  }
}
3.调用

按照之前的方式导包,然后调用工具类的方法即可

Text(StringUtil.getArriveMessage('可以拼接文本'))

import { add, Log, CommonText, StringUtil } from 'common'
import router from '@ohos.router'

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

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            var result = add(1, 2)
            this.message = "result=" + result
            Log.info("----------------")
          })
        CommonText()
          .onClick(() => {
            router.pushUrl({ url: '@bundle:com.lf.myapplication/Common/ets/pages/CommonIndex' })
              .then(() => {
                console.log("push page success");
              })
              .catch(err => {
                console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`);
              })
          })

        Text(StringUtil.getArriveMessage('可以拼接文本'))
      }
      .width('100%')
    }
    .height('100%')
  }
}

效果图:

五、跨包使用需要注意点:

  • 要使用HSP中的接口,需要在使用方的oh-package.json5中配置对它的依赖

  • 跨包使用的接口都需要添加export。对外暴露的接口,需要在入口文件index.ets中声明,同一个类的多个方法,可以写在一起,用,隔开

  • 新增的共享包需要跨包调用,需要在Edit Configurations中添加新增的共享包

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1358486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次 .NET 某新能源材料检测系统 崩溃分析

一:背景 1. 讲故事 上周有位朋友找到我,说他的程序经常会偶发性崩溃,一直没找到原因,自己也抓了dump 也没分析出个所以然,让我帮忙看下怎么回事,那既然有 dump,那就开始分析呗。 二&#xff…

计算机创新协会冬令营——暴力枚举题目05

这道题挺基础但是挺多坑的。(•́へ•́╬) 题目 204. 计数质数 - 力扣(LeetCode) 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。 示例 示例 1: 输入:n 10 输出:4 解释:小于 10 的质…

具有大电流,双通道 12V,短地短电源保护等功能的国产芯片GC8549 可替代ONSEMI的LV8548/LV8549

GC8549 可以工作在 3.8~12V 的电源电压上,每 通道能提供高达 1.5A 持续输出电流或者 2.5A 峰值 电流,睡眠模式下功耗小于 1uA。具有 PWM(IN/EN)输入接口,与行业标 准器件兼容,并具有过温保护,欠压保护&…

信息系统项目管理师好考吗?知识点分析与讲解,码住!

科目一:综合知识考试 科目一考试是由选择题组成的,共有75道题目。考试时间为早上9点到11点半,可以提前交卷,通常11点左右就能离开考场。对于会做的题目,要及时解答,对于不会做的题目,花费过多时…

QC/PD快充电源产品MOS选型分析

• 原边650-700V SJ MOSFET采用低FOM值的ESM 技术,有利于提高系统效 率, 以及更佳的EAS和EMI等特性,对于一些不含PFC电路的系统更友好。 • 副边采用低FOM值的SGT同步整流电路,相比肖特基二极管整流能有更低的 损耗,有…

pinia 给 state 指定变量类型

pinia 给 state 指定变量类型 问题描述 自从用 vitetsvue3 以来,我一直有一个很大的疑问,就是 pinia 中的 state 变量类型该从哪定义,如何定义它? 因为我在使用未定义类型的 state 变量的时候一直会有一个提示,提示说…

JAVA集合框架总结

集合框架概述 1.1 生活中的容器 1.2 数组的特点与弊端 一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用数组存储对象方面具有一些弊端,而Java 集合就…

Unity之预制体与变体

PS:不用说了,我在写博客就是在摸鱼 一、预制体 不知道大家小时候有没有看过火影,记得剧情最开始的时候水木哄骗鸣人去偷封印之书,反而让鸣人学会了多重影分身之术: 好了,小编绞尽脑子终于想好怎么向大家介绍预制体了&a…

element中Tree 树形控件实现多选、展开折叠、全选全不选、父子联动、默认展开、默认选中、默认禁用、自定义节点内容、可拖拽节点、手风琴模式

目录 1.代码实现2. 效果图3. 使用到的部分属性说明4. 更多属性配置查看element官网 1.代码实现 <template><div class"TreePage"><el-checkboxv-model"menuExpand"change"handleCheckedTreeExpand($event, menu)">展开/折叠&l…

亚马逊店铺遇到账号申诉模版分享

1.表达诚意&#xff0c;先认错再说&#xff1a;我知道&#xff0c;最近我们在Amazon.com上作为卖家的表现已经低于亚马逊和我们自己的质量标准。 2.清楚分明的格式&#xff1a;我们库存管理的混乱导致了延迟发货&#xff0c;更糟糕的是&#xff0c;物品无法使用。当延迟发货和…

00 项目结构

文章目录 后端 后端 后端 - sky-common包 公共类&#xff0c;工具类&#xff0c;常量类- constant 常量类- context 上下文有关的- enumenation 枚举- exception 自定义异常类- json json处理类- properties boot相关的配置属性类- result 结果类- uti…

【React系列】React中的CSS

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. React中的css方案 1.1. react 中的 css 事实上&#xff0c;css 一直是 React 的痛点&#xff0c;也是被很多开发…

gitlab高级功能之Kubernetes Agent介绍

文章目录 1. 前置条件2. 简介3. GitLab Kubernetes Agent 的部署3.1 启用 Agent 服务端3.2 创建 Agent 配置和清单仓库 4. 安装agent4.1 连接k8s集群4.2 在集群中部署4.3 修改资源清淡&#xff0c;调整pod的副本数 5. 思考 1. 前置条件 gitlab 14.5 专业版k8s集群helm客户端工…

风车模型与代码

这个模型使用NetLogo乌龟来重复绘制圆圈&#xff0c;定期转动&#xff0c;以便显示出类似万花筒或风车的效果。这是一个演示&#xff0c;展示了一组简单的代理规则如何产生复杂而美丽的图案。 内部工作原理非常简单。创建了许多乌龟&#xff0c;它们的笔都是放下的&#xff08…

一文全面了解 LSM BPF (含实战,强烈建议收藏)

本文地址&#xff1a;https://www.ebpf.top/post/lsm_bpf_intro 文章目录 1. 安全背景知识2. 内核安全策略模块通用框架 LSM2.1 LSM 框架介绍2.2 LSM 架构2.3 LSM 中的钩子函数 3. LSM BPF3.1 BCC 实践3.2 libbpf-bootstrap 框架实践 4. 总结5. 附录&#xff1a;LSM 热修内核漏…

Java 支持表情包存储 Incorrect string value: ‘\\xF0\\x9F\\x98\\x8A\\xF0\\x9F...‘

一&#xff0c;前言 最近测试提出了一个比较刁钻的bug 在提交表单数据的时候&#xff0c;支持表情输入&#xff0c;如下 看了一下前端参数&#xff0c;也是正常传递 但是调用接口的时候&#xff0c;后端却报错 Cause: java.sql.SQLException: Incorrect string value: \\xF0…

【python】使用fitz包读取PDF文件报错“ModuleNotFoundError: No module named ‘frontend‘”

【python】使用fitz包读取PDF文件报错“ModuleNotFoundError: No module named ‘frontend’” 正确解决过程 在读取PDF文件时&#xff0c;我使用了fitz包&#xff0c;当使用代码import fitz导入该包时&#xff0c;出现了报错&#xff1a; 于是我直接使用以下代码安装fronten…

技术查漏补缺(1)Logback

一、下定义&#xff1a;Logback是一个开源的日志组件 二、Logback的maven <!--这个依赖直接包含了 logback-core 以及 slf4j-api的依赖--> <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><v…

基于Kettle开发的web版数据集成开源工具(data-integration)-介绍篇

目录 &#x1f4da;第一章 官网介绍&#x1f4d7;目标实现&#xff1a;让kettle使用更简单&#x1f4d7;架构及组成 &#x1f4da;第二章 核心功能&#x1f4da;第三章 对比Kettle&#x1f4d7;工具栏位比对&#x1f4d7;工具栏组件内容比对&#x1f4d7;扩展&#xff1a;WebSp…

【CMake】5. 单项目多模块添加第三方依赖示例工程

CMake 示例工程代码 https://github.com/LABELNET/cmake-simple 单项目单模块示例工程 https://github.com/LABELNET/cmake-simple/tree/main/simple-mod-deps 这里引入 C gRPC 依赖&#xff0c;进行示例 1. 多模块工程 第三方依赖 CMake 多模块工程&#xff0c;这是一个…