Android利用Binder实现进程通信
程序员文章站
2022-09-17 22:44:52
跨进程通信方式有很多,本文仅针对利用Binder实现。创建服务端写一个service类继承service,在onbind方法中返回自己的BInder,在MyBinder的onTransact方法中接受客户端发来的消息,并发送消息到客户端。客户端的消息通过data,readString()方法获取,服务端发送消息通过reply,writerString()方法发送,注意reply.writeNoException()这个方法,服务端如果写了这个方法,客户端获取服务端消息也必须要写reply.readE...
跨进程通信方式有很多,本文仅针对利用Binder实现。
创建服务端
- 写一个service类继承service,在onbind方法中返回自己的BInder,在MyBinder的onTransact方法中接受客户端发来的消息,并发送消息到客户端。客户端的消息通过data,readString()方法获取,服务端发送消息通过reply,writerString()方法发送
注意:reply.writeNoException()这个方法,服务端如果写了这个方法,客户端获取服务端消息也必须要写reply.readException()这个方法。必须成对出现,否则获取不到服务端的消息。
public IBinder onBind(Intent intent) {
MyBinder binder=new MyBinder();
return binder;
}
class MyBinder extends Binder{
@Override
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
if (code == 1) {
String s = data.readString();
Log.i("ReviceService", "客户端发来的消息是 " + s);
reply.writeNoException();
reply.writeString("我是服务端发来的消息");
return true;
}
return super.onTransact(code, data, reply, flags);
}
}
- 在AndroidManifest文件中注册服务,并开启多进程,多进程通过process属性指定,带:号为私有进程
<service android:name=".ReviceService" android:process=":reviceservice">
<intent-filter>
<action android:name="android.intent.action.reviceService"></action>
</intent-filter>
</service>
创建客户端
- 写一个类实现ServiceConnection接口,在onServiceConnected方法中与服务端交互。
可以看到onTransact有四个参数
- code 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;
- data客户端传递过来的参数;
- replay服务器返回回去的值;
- flags标明是否有返回值,0为有(双向),1为没有(单向)。
注意transact()直到服务端的Binder.onTransact()方法调用完成后才返回,所以想获取服务端发送的消息必须在onTransact()方法后获取。否则获取不到服务端发来的消息。
class MessServiceConnect implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Parcel data=Parcel.obtain();
data.writeString("我是客户端发过来的消息");
Parcel reply=Parcel.obtain();
try {
service.transact(1,data,reply,0);
reply.readException();
String s = reply.readString();
Log.i(TAG, "服务端发来的消息: "+s);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
绑定服务
- 用隐式意图绑定服务时注意必须要设置包名,否则会报错
Intent intent=new Intent("android.intent.action.reviceService");
intent.setPackage("com.afscope.video");
MessServiceConnect conn = new MessServiceConnect();
bindService(intent, conn,BIND_AUTO_CREATE);
本文地址:https://blog.csdn.net/AmazonUnicon/article/details/108852006