1e41f4b71Sopenharmony_ci# Connecting to a ServiceAbility 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciIf a ServiceAbility wants to interact with a PageAbility or a ServiceAbility in another application, you must first create a connection by calling [connectAbility()](../reference/apis-ability-kit/js-apis-ability-featureAbility.md#featureabilityconnectability7). This method is defined in the [featureAbility](../reference/apis-ability-kit/js-apis-ability-featureAbility.md) class for the PageAbility and in the [particleAbility](../reference/apis-ability-kit/js-apis-ability-particleAbility.md) class for the ServiceAbility. For details about the connection rules, see [Component Startup Rules](component-startup-rules-fa.md). When using **connectAbility()** to process the callback, pass in the instances of [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md) and [IAbilityConnection](../reference/apis-ability-kit/js-apis-inner-ability-connectOptions.md) of the target ServiceAbility. [IAbilityConnection](../reference/apis-ability-kit/js-apis-inner-ability-connectOptions.md) provides the following callbacks that you should implement. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci**Table 1** IAbilityConnection APIs 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci| API| Description| 10e41f4b71Sopenharmony_ci| -------- | -------- | 11e41f4b71Sopenharmony_ci| onConnect() | Callback invoked when the ServiceAbility is connected.| 12e41f4b71Sopenharmony_ci| onDisconnect() | Callback invoked when the ServiceAbility is disconnected.| 13e41f4b71Sopenharmony_ci| onFailed() | Callback invoked when the connection to the ServiceAbility fails.| 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ciThe following sample code enables the PageAbility to create connection callback instances and connect to the local ServiceAbility: 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci```ts 19e41f4b71Sopenharmony_ciimport featureAbility from '@ohos.ability.featureAbility'; 20e41f4b71Sopenharmony_ciimport common from '@ohos.app.ability.common'; 21e41f4b71Sopenharmony_ciimport Want from '@ohos.app.ability.Want'; 22e41f4b71Sopenharmony_ciimport promptAction from '@ohos.promptAction'; 23e41f4b71Sopenharmony_ciimport rpc from '@ohos.rpc'; 24e41f4b71Sopenharmony_ciimport hilog from '@ohos.hilog'; 25e41f4b71Sopenharmony_ci``` 26e41f4b71Sopenharmony_ci```ts 27e41f4b71Sopenharmony_ciconst TAG: string = 'PageServiceAbility'; 28e41f4b71Sopenharmony_ciconst domain: number = 0xFF00; 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci@Entry 31e41f4b71Sopenharmony_ci@Component 32e41f4b71Sopenharmony_cistruct PageServiceAbility { 33e41f4b71Sopenharmony_ci //... 34e41f4b71Sopenharmony_ci build() { 35e41f4b71Sopenharmony_ci Column() { 36e41f4b71Sopenharmony_ci //... 37e41f4b71Sopenharmony_ci List({ initialIndex: 0 }) { 38e41f4b71Sopenharmony_ci ListItem() { 39e41f4b71Sopenharmony_ci Row() { 40e41f4b71Sopenharmony_ci //... 41e41f4b71Sopenharmony_ci } 42e41f4b71Sopenharmony_ci .onClick(() => { 43e41f4b71Sopenharmony_ci let option: common.ConnectOptions = { 44e41f4b71Sopenharmony_ci onConnect: (element, proxy) => { 45e41f4b71Sopenharmony_ci hilog.info(domain, TAG, `onConnectLocalService onConnectDone element:` + JSON.stringify(element)); 46e41f4b71Sopenharmony_ci if (proxy === null) { 47e41f4b71Sopenharmony_ci promptAction.showToast({ 48e41f4b71Sopenharmony_ci message: 'connect_service_failed_toast' 49e41f4b71Sopenharmony_ci }); 50e41f4b71Sopenharmony_ci return; 51e41f4b71Sopenharmony_ci } 52e41f4b71Sopenharmony_ci let data = rpc.MessageParcel.create(); 53e41f4b71Sopenharmony_ci let reply = rpc.MessageParcel.create(); 54e41f4b71Sopenharmony_ci let option = new rpc.MessageOption(); 55e41f4b71Sopenharmony_ci data.writeInterfaceToken('connect.test.token'); 56e41f4b71Sopenharmony_ci proxy.sendRequest(0, data, reply, option); 57e41f4b71Sopenharmony_ci promptAction.showToast({ 58e41f4b71Sopenharmony_ci message: 'connect_service_success_toast' 59e41f4b71Sopenharmony_ci }); 60e41f4b71Sopenharmony_ci }, 61e41f4b71Sopenharmony_ci onDisconnect: (element) => { 62e41f4b71Sopenharmony_ci hilog.info(domain, TAG, `onConnectLocalService onDisconnectDone element:${element}`); 63e41f4b71Sopenharmony_ci promptAction.showToast({ 64e41f4b71Sopenharmony_ci message: 'disconnect_service_success_toast' 65e41f4b71Sopenharmony_ci }); 66e41f4b71Sopenharmony_ci }, 67e41f4b71Sopenharmony_ci onFailed: (code) => { 68e41f4b71Sopenharmony_ci hilog.info(domain, TAG, `onConnectLocalService onFailed errCode:${code}`); 69e41f4b71Sopenharmony_ci promptAction.showToast({ 70e41f4b71Sopenharmony_ci message: 'connect_service_failed_toast' 71e41f4b71Sopenharmony_ci }); 72e41f4b71Sopenharmony_ci } 73e41f4b71Sopenharmony_ci }; 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci let request: Want = { 76e41f4b71Sopenharmony_ci bundleName: 'com.samples.famodelabilitydevelop', 77e41f4b71Sopenharmony_ci abilityName: 'com.samples.famodelabilitydevelop.ServiceAbility', 78e41f4b71Sopenharmony_ci }; 79e41f4b71Sopenharmony_ci let connId = featureAbility.connectAbility(request, option); 80e41f4b71Sopenharmony_ci hilog.info(domain, TAG, `onConnectLocalService onFailed errCode:${connId}`); 81e41f4b71Sopenharmony_ci }) 82e41f4b71Sopenharmony_ci } 83e41f4b71Sopenharmony_ci //... 84e41f4b71Sopenharmony_ci } 85e41f4b71Sopenharmony_ci //... 86e41f4b71Sopenharmony_ci } 87e41f4b71Sopenharmony_ci //... 88e41f4b71Sopenharmony_ci } 89e41f4b71Sopenharmony_ci} 90e41f4b71Sopenharmony_ci``` 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ciWhen the ServiceAbility is connected, the [onConnect()](../reference/apis-ability-kit/js-apis-inner-ability-connectOptions.md#onconnect) callback is invoked and returns an [IRemoteObject](../reference/apis-ipc-kit/js-apis-rpc.md#iremoteobject) defining the proxy used for communicating with the ServiceAbility. The system provides a default implementation of **IRemoteObject**. You can extend [rpc.RemoteObject](../reference/apis-ipc-kit/js-apis-rpc.md#remoteobject) to implement your own class of **IRemoteObject**. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ciThe following sample code shows how the ServiceAbility returns itself to the caller: 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci```ts 99e41f4b71Sopenharmony_ciimport type Want from '@ohos.app.ability.Want'; 100e41f4b71Sopenharmony_ciimport rpc from '@ohos.rpc'; 101e41f4b71Sopenharmony_ciimport hilog from '@ohos.hilog'; 102e41f4b71Sopenharmony_ci 103e41f4b71Sopenharmony_ciconst TAG: string = '[Sample_FAModelAbilityDevelop]'; 104e41f4b71Sopenharmony_ciconst domain: number = 0xFF00; 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ciclass FirstServiceAbilityStub extends rpc.RemoteObject { 107e41f4b71Sopenharmony_ci constructor(des: Object) { 108e41f4b71Sopenharmony_ci if (typeof des === 'string') { 109e41f4b71Sopenharmony_ci super(des); 110e41f4b71Sopenharmony_ci } else { 111e41f4b71Sopenharmony_ci return; 112e41f4b71Sopenharmony_ci } 113e41f4b71Sopenharmony_ci } 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ci onRemoteRequest(code: number, data: rpc.MessageParcel, reply: rpc.MessageParcel, option: rpc.MessageOption): boolean { 116e41f4b71Sopenharmony_ci hilog.info(domain, TAG, 'ServiceAbility onRemoteRequest called'); 117e41f4b71Sopenharmony_ci if (code === 1) { 118e41f4b71Sopenharmony_ci let string = data.readString(); 119e41f4b71Sopenharmony_ci hilog.info(domain, TAG, `ServiceAbility string=${string}`); 120e41f4b71Sopenharmony_ci let result = Array.from(string).sort().join(''); 121e41f4b71Sopenharmony_ci hilog.info(domain, TAG, `ServiceAbility result=${result}`); 122e41f4b71Sopenharmony_ci reply.writeString(result); 123e41f4b71Sopenharmony_ci } else { 124e41f4b71Sopenharmony_ci hilog.info(domain, TAG, 'ServiceAbility unknown request code'); 125e41f4b71Sopenharmony_ci } 126e41f4b71Sopenharmony_ci return true; 127e41f4b71Sopenharmony_ci } 128e41f4b71Sopenharmony_ci} 129e41f4b71Sopenharmony_ci//... 130e41f4b71Sopenharmony_ci``` 131