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