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