ResultReceiver 扩展(双向通信)

6 阅读2分钟

前言

经过上一章 # 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)