Binder
程序运行的地址是虚拟地址
进程A 向进程B通信
mmap 映射了一块地址给进程B
内存共享 技术没问题 一次拷贝都不需要
使用困难(例如 怎样通知进程B去取数据)
Binder 一次拷贝 帮你封装了内核态 和通知
使用前置条件
需要配置
android{ ``` buildFeatures { aidl = true } ``` }
不然 创建aidl 文件是灰色的 AIDL File(requires setting the buildFeatures.aidl to true in the build file)
使用
client---->Service
需要定义通讯的接口 aidl
aidl会帮你生成Binder
public static abstract class Stub extends android.os.Binder implements com.example.android.service.IHMAidl
C-->S
Client拿到Service的Binder发送数据 Service实现了Binder
Service
service:创建服务时传入 aild生成的binder
public class AidlService extends Service { public AidlService() { } public static final String TAG=AidlService.class.getSimpleName(); @Override public IBinder onBind(Intent intent) { return iBinder; } private IBinder iBinder=new IHMAidl.Stub() { @Override public void sendData(String name) throws RemoteException { Log.e(TAG, "rec data: "+name ); } }; }
Client
client:通过bindServie 拿到bind
private void bindService() { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.android.service", "com.example.android.service.AidlService")); bindService(intent, connection, Context.BIND_AUTO_CREATE); } private IHMAidl ihmAidl; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e(TAG, "onServiceConnected: suc "); ihmAidl = IHMAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { Log.e(TAG, "onServiceDisconnected: suc "); } };
S-->C
Client 通过Binder注册一个Callback到Service Service拿到CallBack发数据
// IDataToClientAidl.aidl package com.io.service; // Declare any non-default types here with import statements interface IDataToClientAidl { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void sendDataToClient(in String data); }
Service
class AidlService : Service() { override fun onBind(intent: Intent): IBinder { return binder } private val binder = object : IHMAidl.Stub() { override fun sendData(name: String) { MyLogger.hLog().e("接收到客户端的数据:$name") } override fun registerCallback(callback: IDataToClientAidl) { iDataToClientAidl = callback } } companion object{ var iDataToClientAidl: IDataToClientAidl? = null } }
Client
private fun bindServie() { val intent= Intent() intent.component = ComponentName("com.io.service","com.io.service.AidlService") bindService(intent,object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { iHMAidl= IHMAidl.Stub.asInterface(service) iHMAidl.sendData("num:${num}") iHMAidl.registerCallback(object : IDataToClientAidl.Stub(){ override fun sendDataToClient(name: String?) { tvContent.text=name } }) } override fun onServiceDisconnected(name: ComponentName?) { } }, Context.BIND_AUTO_CREATE) }
Binder对比共享内存
缺点:Binder需要一次拷贝 共享内存无需拷贝
优点:Binder IPC通信 只用写客户端代码 bindService 使用简单 不需要copy_from_user mmap 通知进程B