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.gitandroid

相關文章
相關標籤/搜索