1.大致流程
- 在服务端声明远程服务接口IRemoteService.aidl,并声明回调接口ICallback.aidl
- 在服务端实现远程服务接口IRemoteService.Stub
- 使用RemoteCallbackList保存回调接口列表
- 发布服务
- 在客户端实现回调接口 ICallback.Stub
- 绑定服务,注册回调接口
- 调用服务
- 远程服务从RemoteCallbackList中找到回调,然后调用.
2.服务端
2.1 声明服务接口IRemoteService.aidl
1 // IRemoteService.aidl
2 package com.example.ee.aidl;
3
4 import com.example.ee.aidl.ICallback;
5
6 interface IRemoteService {
7
8 int getPid();
9 oneway void fun1();
10 void registerCallback(ICallback cb);
11 void unregisterCallback(ICallback cb);
12 }
2.2 声明回调接口ICallback.aidl
1 // ICallback.aidl
2 package com.example.ee.aidl;
3
4
5 interface ICallback {
6 oneway void fun2();
7 }
2.3 实现服务,用 RemoteCallbackList 保存回调接口.
1 package com.example.ee.aidl;
2
3 import android.app.Service;
4 import android.content.Intent;
5 import android.os.IBinder;
6 import android.os.Process;
7 import android.os.RemoteCallbackList;
8 import android.os.RemoteException;
9 import android.support.annotation.Nullable;
10 import android.util.Log;
11
12 public class RemoteService extends Service {
13 final String TAG = "RemoteService";
14
15 private RemoteBinder binder = new RemoteBinder();
16 private RemoteCallbackList<ICallback> callbackList = new RemoteCallbackList<>();
17
18 @Nullable
19 @Override
20 public IBinder onBind(Intent intent) {
21 return binder;
22 }
23
24 class RemoteBinder extends IRemoteService.Stub{
25
26 void callback(){
27 int count = callbackList.beginBroadcast();
28 try {
29 for (int i = 0; i < count; i++) {
30 callbackList.getBroadcastItem(i).fun2();
31 }
32 } catch (RemoteException e) {
33 Log.e(TAG, e.getMessage());
34 } finally {
35 }
36 callbackList.finishBroadcast();
37 }
38
39
40 @Override
41 public int getPid() throws RemoteException {
42 return Process.myPid();
43 }
44
45 @Override
46 public void fun1() throws RemoteException {
47 Log.d(TAG, "fun1 in remote service ");
48 callback();
49 }
50
51 @Override
52 public void registerCallback(ICallback cb) throws RemoteException {
53 callbackList.register(cb);
54 }
55
56 @Override
57 public void unregisterCallback(ICallback cb) throws RemoteException {
58 callbackList.unregister(cb);
59 }
60 }
61 }
2.4 发布服务
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="com.example.ee.aidl">
4
5 <application
6 android:allowBackup="false"
7 android:icon="@mipmap/ic_launcher"
8 android:label="@string/app_name"
9 android:roundIcon="@mipmap/ic_launcher_round"
10 android:supportsRtl="true"
11 android:name=".AidlApp"
12 android:theme="@style/AppTheme">
13 <!--<meta-data
14 android:name="APP_CHANNEL"
15 android:value="${APP_CHANNEL}" />
16 -->
17 <activity android:name=".MainActivity">
18 <intent-filter>
19 <action android:name="android.intent.action.MAIN" />
20
21 <category android:name="android.intent.category.LAUNCHER" />
22 </intent-filter>
23 </activity>
24 <service android:name=".RemoteService" android:process=".RemoteService" android:exported="true"/>
25 </application>
26
27 </manifest>
3.客户端
3.1 实现回调接口
1 private ICallback callback = new ICallback.Stub(){
2
3 @Override
4 public void fun2() throws RemoteException {
5 Log.d(TAG, "fun2 in client ");
6 }
7 };
3.2 绑定远程服务,注册回调
1 private void bindRemoteService(){
2 connection = new ServiceConnection() {
3 @Override
4 public void onServiceConnected(ComponentName name, IBinder service) {
5 remoteService = IRemoteService.Stub.asInterface(service);
6 try {
7 remoteService.registerCallback(callback);
8 } catch (RemoteException e) {
9 e.printStackTrace();
10 }
11 }
12
13 @Override
14 public void onServiceDisconnected(ComponentName name) {
15
16 }
17 };
18
19 Intent intent = new Intent(this,RemoteService.class);
20 boolean ret = bindService(intent,connection, BIND_AUTO_CREATE);
21 if (!ret ){
22 Log.e(TAG, "bindRemoteService: bind failed.");
23 }
24 }
3.3 调用远程服务
1 public void onClick(View view){
2 if(view.getId() == R.id.btn_call_remote){
3 AidlApp app = (AidlApp) getApplication();
4 if (app.remoteService != null){
5 try {
6 int pid = app.remoteService.getPid();
7 Log.d(TAG, "onServiceConnected: remote pid = " + pid);
8 app.remoteService.fun1();
9 } catch (RemoteException e) {
10 e.printStackTrace();
11 }
12 }else {
13 Snackbar.make(view,"remote service unbinded",Snackbar.LENGTH_SHORT).show();
14 }
15 }
16 }
4. 远程服务调用回调
1 void callback(){
2 int count = callbackList.beginBroadcast();
3 try {
4 for (int i = 0; i < count; i++) {
5 callbackList.getBroadcastItem(i).fun2();
6 }
7 } catch (RemoteException e) {
8 Log.e(TAG, e.getMessage());
9 } finally {
10 }
11 callbackList.finishBroadcast();
12 }
5.下载
https://gitee.com/xi/RemoteCallbackList.git