# AIDLSample **Repository Path**: ZhangQQ_123/AIDLSample ## Basic Information - **Project Name**: AIDLSample - **Description**: AIDL实现跨进程通信 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2020-10-08 - **Last Updated**: 2021-04-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AIDLSample #### 介绍 AIDL实现跨进程通信 #### 使用说明 1. 定义一个服务 ``` public class RemoteService extends Service { private MyBinder binder = new MyBinder(); public class MyBinder extends Binder { public void showMessage() { Toast.makeText(RemoteService.this, "与服务通信", Toast.LENGTH_LONG).show(); } } @Nullable @Override public IBinder onBind(Intent intent) { return binder; } } ``` 2. 声明为远程服务 ``` ``` 3. 如果这时候使用bindService与服务通信,如下: ``` private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { RemoteService.MyBinder myBinder = (RemoteService.MyBinder) service; myBinder.showMessage(); } @Override public void onServiceDisconnected(ComponentName name) { } }; ``` - 会报如下错误: ``` 2020-10-08 16:12:50.960 15369-15369/com.study.aidlsample E/AndroidRuntime: FATAL EXCEPTION: main Process: com.study.aidlsample, PID: 15369 java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.study.aidlsample.service.RemoteService$MyBinder ``` ## 所以需要使用跨进程通信,流程如下: 1. 定义AIDL(安卓接口定义语言) 2. 定义好AIDL后编译以下会在build/generated/aidl_source_output_dir/debug/out下生成一个android.os.IInterface接口的子接口,并修改服务中的Binder,如下: ``` /** * 拿到AIDL帮我们生成的Binder对象 * 并且我们在AIDL定义的方法,在这里都进行了回调 */ IBinder iMessageSender = new IMessageSender.Stub() { @Override public void sendMessage(Message message) throws RemoteException { } @Override public void registerReceiveListener(IMessageReceiver messageReceiver) throws RemoteException { } @Override public void unregisterReceiveListener(IMessageReceiver messageReceiver) throws RemoteException { } }; ``` 3. 在MainActivity中绑定服务作如下修改: ``` private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //获取到服务给我们返回的Binder对象,并转换成IMessageSender对象 iMessageSender = IMessageSender.Stub.asInterface(service); Message message = new Message(); message.content = "这是消息的内容"; message.from = "消息来自:" + MainActivity.class.getName(); message.to = "消息要发送给:" + RemoteService.class.getName(); try { iMessageSender.sendMessage(message); iMessageSender.registerReceiveListener(iMessageReceiver); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { Log.e(MainActivity.class.getName(), "服务连接断开"); } }; ``` - 并在RemoteService的new IMessageSender.Stub()回调中打印结果 ``` @Override public void sendMessage(Message message) throws RemoteException { Log.e("RemoteService", message.toString()); } ``` - 输出的结果为: ``` 2020-10-08 17:20:02.632 16480-16493/com.study.aidlsample E/RemoteService: Message{content='这是消息的内容', from='消息来自:com.study.aidlsample.MainActivity', to='消息要发送给:com.study.aidlsample.service.RemoteService'} ``` - 至此已经完成了盐城服务的单向通信,接下来把iMessageReceiver注册到远程服务实现双向通信 ``` IBinder iMessageSender = new IMessageSender.Stub() { @Override public void sendMessage(Message message) throws RemoteException { Log.e("RemoteService", message.toString()); } @Override public void registerReceiveListener(IMessageReceiver messageReceiver) throws RemoteException { callbackList.register(messageReceiver); } @Override public void unregisterReceiveListener(IMessageReceiver messageReceiver) throws RemoteException { callbackList.unregister(messageReceiver); } }; /** * 实现Runnable接口,执行任务 */ class Task implements Runnable { @Override public void run() { //服务没被销毁就一直运行 while (!isServiceDestroy.get()) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } Message message = new Message(); message.setFrom(RemoteService.class.getName()); message.setTo(MainActivity.class.getName()); message.setContent(String.valueOf(new Date().getTime())); //开始遍历远程接口回调,执行完注意finishBroadcast() int receiverCount = callbackList.beginBroadcast(); for (int i = 0; i < receiverCount; i++) { try { //调用信息回调 callbackList.getBroadcastItem(i).onMessageReceived(message); } catch (RemoteException e) { e.printStackTrace(); } } callbackList.finishBroadcast(); } } } ```