1# Connecting to a ServiceAbility 2 3 4If a ServiceAbility wants to interact with a PageAbility or a ServiceAbility in another application, you must first create a connection by calling **connectAbility()**. This method is defined in the **featureAbility** class for the PageAbility and in the **particleAbility** class for the ServiceAbility. For details about the connection rules, see [Component Startup Rules](component-startup-rules.md). When calling **connectAbility()**, you should pass in a **Want** object containing information about the target ServiceAbility and an **IAbilityConnection** object. **IAbilityConnection** provides the following APIs that you need to implement. 5 6**Table 1** IAbilityConnection APIs 7 8| API| Description| 9| -------- | -------- | 10| onConnect() | Callback invoked when the ServiceAbility is connected.| 11| onDisconnect() | Callback invoked when the ServiceAbility is disconnected.| 12| onFailed() | Callback invoked when the connection to the ServiceAbility fails.| 13 14 15The following sample code enables the PageAbility to create connection callback instances and connect to the local ServiceAbility: 16 17```ts 18import rpc from "@ohos.rpc" 19import promptAction from '@ohos.promptAction' 20import featureAbility from '@ohos.ability.featureAbility' 21import common from '@ohos.app.ability.common'; 22import Want from '@ohos.app.ability.Want'; 23 24let option: common.ConnectOptions = { 25 onConnect: (element, proxy) => { 26 console.info(`onConnectLocalService onConnectDone`) 27 if (proxy === null) { 28 promptAction.showToast({ 29 message: "Connect service failed" 30 }) 31 return 32 } 33 let data = rpc.MessageParcel.create() 34 let reply = rpc.MessageParcel.create() 35 let option = new rpc.MessageOption() 36 data.writeInterfaceToken("connect.test.token") 37 proxy.sendRequest(0, data, reply, option) 38 promptAction.showToast({ 39 message: "Connect service success" 40 }) 41 }, 42 onDisconnect: (element) => { 43 console.info(`onConnectLocalService onDisconnectDone element:${element}`) 44 promptAction.showToast({ 45 message: "Disconnect service success" 46 }) 47 }, 48 onFailed: (code) => { 49 console.info(`onConnectLocalService onFailed errCode:${code}`) 50 promptAction.showToast({ 51 message: "Connect local service onFailed" 52 }) 53 } 54}; 55 56let request: Want = { 57 bundleName: "com.example.myapplication", 58 abilityName: "com.example.myapplication.ServiceAbility", 59} 60let connId = featureAbility.connectAbility(request, option) 61``` 62 63 64When the ServiceAbility is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the ServiceAbility. OpenHarmony provides a default implementation of **IRemoteObject**. You can extend **rpc.RemoteObject** to implement your own class of **IRemoteObject**. 65 66 67The following sample code shows how the ServiceAbility returns itself to the caller: 68 69```ts 70import rpc from "@ohos.rpc" 71 72class FirstServiceAbilityStub extends rpc.RemoteObject { 73 constructor(des: Object) { 74 if (typeof des === 'string') { 75 super(des) 76 } else { 77 return 78 } 79 } 80 81 onRemoteRequest(code: number, data: rpc.MessageParcel, reply: rpc.MessageParcel, option: rpc.MessageOption) { 82 console.info(`onRemoteRequest called`) 83 if (code === 1) { 84 let string = data.readString() 85 console.info(`string=${string}`) 86 let result = Array.from(string).sort().join('') 87 console.info(`result=${result}`) 88 reply.writeString(result) 89 } else { 90 console.info(`unknown request code`) 91 } 92 return true 93 } 94} 95``` 96