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