AIDL(2):服务端回调客户端

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

 

posted @ 2017-10-10 14:41  f9q  阅读(850)  评论(0编辑  收藏  举报