前言
经过上一章 # ResultReceiver源码解析 的学习,我们了解到通过ResultReceiver可以实现跨进程通信,但是这里也有一个缺点,是他只能单向通信类似于一个回调。
那么,如何实现双向通信呢?
方式一
通过对ResultReceiver进行简单的扩展,实现该功能
/**
* 双工ResultReceiver,通过内部额外持有一个ResultReceiver实现
*/
public class FullResultReceiver extends ResultReceiver {
public FullResultReceiver(Handler handler) {
super(handler);
}
//内部持有一个mResultReceiver,通过在远端创建的方式,实现双向通信
private ResultReceiver mResultReceiver;
@Override
protected final void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == 1000) {
mResultReceiver = resultData.getParcelable("result");
} else {
onResult(resultCode, resultData);
}
}
public ResultReceiver getResultReceiver() {
return mResultReceiver;
}
public void sendReceiver(ResultReceiver resultReceiver) {
Bundle bundle = new Bundle();
bundle.putParcelable("result", resultReceiver);
send(1000, bundle);
}
protected void onResult(int resultCode, Bundle resultData) {
}
}
使用
//近端 接收远端数据
var receiver = object : FullResultReceiver(null){
override fun onResult(resultCode: Int, resultData: Bundle?) {
super.onResult(resultCode, resultData)
}
}
//近端发送数据给远端
receiver2.resultReceiver.send(1,null)
//远端接收近端数据
receiver.sendReceiver(object : ResultReceiver(null) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
super.onReceiveResult(resultCode, resultData)
}
})
//远端发送数据给近端
receiver.send(1, null)
方式二
通过仿照ResultReceiver实现方式,自定义实现
/**
* 双工ResultReceiver,通过仿照ResultReceiver实现方式,自定义实现
*/
public class DuplexResultReceiver implements Parcelable {
final boolean mLocal;//用于区分是本地还是远端
final Handler mHandler;//控制回调线程
IDuplexResultReceiver mReceiver; //给远端使用,序列化时创建
public DuplexResultReceiver(Handler handler) {
mLocal = true;
mHandler = handler;
}
public void send(int resultCode, Bundle resultData) {
//本地使用
if (mLocal) {
if (mHandler != null) {
mHandler.post(new MyRunnable(resultCode, resultData));
} else {
onReceiveResult(resultCode, resultData);
}
return;
}
//远端使用
if (mReceiver != null) {
try {
mReceiver.onReceiveResult(resultCode, resultData);
} catch (RemoteException e) {
}
}
}
public void setResultReceiver(ResultReceiver receiver) {
//本地使用
if (mLocal) {
mResultReceiver = receiver;
return;
}
//远端使用
if (mReceiver != null) {
try {
mReceiver.setResultReceiver(receiver);
} catch (RemoteException e) {
}
}
}
/***
* 接收远端回调的信息
*/
protected void onReceiveResult(int resultCode, Bundle resultData) {
}
private ResultReceiver mResultReceiver;
public @Nullable ResultReceiver getResultReceiver() {
return mResultReceiver;
}
class MyRunnable implements Runnable {
final int mResultCode;
final Bundle mResultData;
MyRunnable(int resultCode, Bundle resultData) {
mResultCode = resultCode;
mResultData = resultData;
}
public void run() {
onReceiveResult(mResultCode, mResultData);
}
}
class MyResultReceiver extends IDuplexResultReceiver.Stub {
@Override
public void setResultReceiver(android.os.ResultReceiver receiver) throws RemoteException {
mResultReceiver = receiver;
}
@Override
public void onReceiveResult(int code, Bundle bundle) throws RemoteException {
DuplexResultReceiver.this.onReceiveResult(code, bundle);
}
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
//序列化传递时,仅传递了mReceiver 字段
synchronized (this) {
if (mReceiver == null) {
mReceiver = new MyResultReceiver();
}
out.writeStrongBinder(mReceiver.asBinder());
}
}
DuplexResultReceiver(Parcel in) {
//反序列化时,仅能读取到mReceiver 字段,
mLocal = false;
mHandler = null;
mReceiver = IDuplexResultReceiver.Stub.asInterface(in.readStrongBinder());
}
public static final Creator<DuplexResultReceiver> CREATOR = new Creator<DuplexResultReceiver>() {
@Override
public DuplexResultReceiver createFromParcel(Parcel in) {
return new DuplexResultReceiver(in);
}
@Override
public DuplexResultReceiver[] newArray(int size) {
return new DuplexResultReceiver[size];
}
};
}
使用
//近端 接收远端数据
var receiver: DuplexResultReceiver? = object : DuplexResultReceiver(Handler()) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
super.onReceiveResult(resultCode, resultData)
tw2.text = "bToa:" + bToa++
}
}
//近端发送数据给远端
receiver?.resultReceiver?.send(2, null)
//远端接收近端数据
receiver?.resultReceiver = object : ResultReceiver(null) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
super.onReceiveResult(resultCode, resultData)
tw1.text = "aTob:" + aTob++
}
}
//远端发送数据给近端
receiver?.send(1, null)