• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# In-Application HSP Development
2
3An in-application Harmony Shared Package (HSP) is a file used for code and resource sharing within an application (called the host application) and can only be invoked by a HAP or HSP of the same application.
4The in-application HSP is released with the Application Package (App Pack) of the host application, shares a process with the host application, and has the same bundle name and lifecycle as the host application.
5
6## Developing an In-Application HSP
7
8You can kickstart your HSP development with the HSP template in DevEco Studio. In this example, an HSP module named **library** is created. The basic project directory structure is as follows:
9```
10library
11├── src
12│   └── main
13│       ├── ets
14│       │   ├── pages
15│       │   └── index.ets
16│       ├── resources
17│       └── module.json5
18└── oh-package.json5
19```
20In the **module.json5** file, set **type** to **shared** for the HSP.
21```json
22{
23    "type": "shared"
24}
25```
26
27The HSP provides capabilities for external systems by exporting APIs in the entry file. Specify the entry file in **main** in the **oh-package.json5** file. For example:
28```json
29{
30    "main": "./src/main/ets/index.ets"
31}
32```
33
34### Exporting TS Classes and Methods
35Use **export** to export TS classes and methods. The sample code is as follows:
36```ts
37// library/src/main/ets/utils/test.ts
38export class Log {
39    static info(msg) {
40        console.info(msg);
41    }
42}
43
44export function add(a: number, b: number) {
45  return a + b;
46}
47
48export function minus(a: number, b: number) {
49  return a - b;
50}
51```
52In the entry file **index.ets**, declare the APIs to be exposed.
53```ts
54// library/src/main/ets/index.ets
55export { Log, add, minus } from './utils/test'
56```
57
58### Exporting ArkUI Components
59Use **export** to export ArkUI components. The sample code is as follows:
60```ts
61// library/src/main/ets/components/MyTitleBar.ets
62@Component
63export struct MyTitleBar {
64  build() {
65    Row() {
66      Text($r('app.string.library_title'))
67        .fontColor($r('app.color.white'))
68        .fontSize(25)
69        .margin({left:15})
70    }
71    .width('100%')
72    .height(50)
73    .padding({left:15})
74    .backgroundColor('#0D9FFB')
75  }
76}
77```
78In the entry file **index.ets**, declare the APIs to be exposed.
79```ts
80// library/src/main/ets/index.ets
81export { MyTitleBar } from './components/MyTitleBar'
82```
83#### About Using Resources in the HSP
84To reference resources in the **resources** directory of the current HSP module, use **$r** or **$rawfile**.
85If a relative path is used, the resources in the HSP caller are referenced instead. For example,
86if **Image("common/example.png")** is used in the HSP module, the **\<Image>** component will reference the resource **entry/src/main/ets/common/example.png** in the HSP caller (which is **entry** in this example).
87
88### Exporting Native Methods
89The HSP can contain .so files compiled in C++. The HSP indirectly exports the native method in the .so file. In this example, the **multi** method in the **libnative.so** file is exported.
90```ts
91// ibrary/src/main/ets/utils/nativeTest.ts
92import native from "libnative.so"
93
94export function nativeMulti(a: number, b: number) {
95    return native.multi(a, b);
96}
97```
98
99In the entry file **index.ets**, declare the APIs to be exposed.
100```ts
101// library/src/main/ets/index.ets
102export { nativeMulti } from './utils/nativeTest'
103```
104
105## Using the In-Application HSP
106To use APIs in the HSP, first configure the dependency on the HSP in the **oh-package.json5** file of the module that needs to call the APIs (called the invoking module). If the HSP and the invoking module are in the same project, the APIs can be referenced locally. The sample code is as follows:
107```json
108// entry/oh-package.json5
109"dependencies": {
110    "library": "file:../library"
111}
112```
113You can now call the external APIs of the HSP in the same way as calling the APIs in the HAR.
114In this example, the external APIs are the following ones exported from **library**:
115```ts
116// library/src/main/ets/index.ets
117export { Log, add, minus } from './utils/test'
118export { MyTitleBar } from './components/MyTitleBar'
119export { nativeMulti } from './utils/nativeTest'
120```
121The APIs can be used as follows in the code of the invoking module:
122```ts
123// entry/src/main/ets/pages/index.ets
124import { Log, add, MyTitleBar, nativeMulti } from "library"
125
126@Entry
127@Component
128struct Index {
129  @State message: string = 'Hello World'
130  build() {
131    Row() {
132      Column() {
133        MyTitleBar()
134        Text(this.message)
135          .fontSize(30)
136          .fontWeight(FontWeight.Bold)
137        Button('add(1, 2)')
138          .onClick(()=>{
139            Log.info("add button click!");
140            this.message = "result: " + add(1, 2);
141          })
142        Button('nativeMulti(3, 4)')
143          .onClick(()=>{
144            Log.info("nativeMulti button click!");
145            this.message = "result: " + nativeMulti(3, 4);
146          })
147      }
148      .width('100%')
149    }
150    .height('100%')
151  }
152}
153```
154
155### Redirecting to a Page in Another Bundle
156
157If you want to add a button in the **entry** module to jump to the menu page (**library/src/main/ets/pages/menu.ets**) in the **library** module, you can write the following code in the **entry/src/main/ets/MainAbility/Index.ets** file of the **entry** module:
158```ts
159import router from '@ohos.router';
160
161@Entry
162@Component
163struct Index {
164    @State message: string = 'Hello World'
165
166    build() {
167    Row() {
168        Column() {
169        Text(this.message)
170            .fontSize(50)
171            .fontWeight(FontWeight.Bold)
172        // Add a button to respond to user clicks.
173        Button() {
174            Text('click to menu')
175            .fontSize(30)
176            .fontWeight(FontWeight.Bold)
177        }
178        .type(ButtonType.Capsule)
179        .margin({
180            top: 20
181        })
182        .backgroundColor('#0D9FFB')
183        .width('40%')
184        .height('5%')
185        // Bind click events.
186        .onClick(() => {
187            router.pushUrl({
188              url: '@bundle:com.example.hmservice/library/ets/pages/menu'
189            }).then(() => {
190              console.log("push page success");
191            }).catch(err => {
192              console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`);
193            })
194        })
195      .width('100%')
196    }
197    .height('100%')
198    }
199  }
200}
201```
202The input parameter **url** of the **router.pushUrl** API is as follows:
203```ets
204'@bundle:com.example.hmservice/library/ets/pages/menu'
205```
206The **url** content template is as follows:
207```ets
208'@bundle:bundle name/module name/path/page file name (without the extension .ets)'
209```
210