ResultReceiver源码解析

38 阅读2分钟

是什么

Android 提供的,一个用于接收回调的通用接口,同时支持跨进程,支持设置handler 选择处理回调的线程

使用场景

四大组件进程间、进程内简单回调处理

源码解析:重点关注代码中中文注释部分

  • 通过序列化阶段不完全序列化所有成员变量的方式,实现同一段代码,自动区分远端和本地执行不同逻辑分支
  • 通过IResultReceiver,实现跨进程回调
  • 通过Handler 切换到想要处理回调的线程

public class ResultReceiver implements Parcelable {
    final boolean mLocal;
    final Handler mHandler;
    
    IResultReceiver mReceiver;
    
    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 IResultReceiver.Stub {
        public void send(int resultCode, Bundle resultData) {
            if (mHandler != null) {
                mHandler.post(new MyRunnable(resultCode, resultData));
            } else {
                onReceiveResult(resultCode, resultData);
            }
        }
    }
    
    /**
     * Create a new ResultReceive to receive results.  Your
     * {@link #onReceiveResult} method will be called from the thread running
     * <var>handler</var> if given, or from an arbitrary thread if null.
     */
    public ResultReceiver(Handler handler) {
        mLocal = true;
        mHandler = handler;
    }
    
    /**
     * Deliver a result to this receiver.  Will call {@link #onReceiveResult},
     * always asynchronously if the receiver has supplied a Handler in which
     * to dispatch the result.
     * @param resultCode Arbitrary result code to deliver, as defined by you.
     * @param resultData Any additional data provided by you.
     */
    public void send(int resultCode, Bundle resultData) {
        
        //对于ResultReceiver的创建方,走这个方法
        if (mLocal) {
            if (mHandler != null) {
                mHandler.post(new MyRunnable(resultCode, resultData));
            } else {
                onReceiveResult(resultCode, resultData);
            }
            return;
        }
        //对于ResultReceiver的使用方,走这个方法
        if (mReceiver != null) {
            try {
                //这里实际在调用创建方的send方法
                mReceiver.send(resultCode, resultData);
            } catch (RemoteException e) {
            }
        }
    }
    
    /**
     * Override to receive results delivered to this object.
     * 
     * @param resultCode Arbitrary result code delivered by the sender, as
     * defined by the sender.
     * @param resultData Any additional data provided by the sender.
     */
    protected void onReceiveResult(int resultCode, Bundle resultData) {
    }
    
    public int describeContents() {
        return 0;
    }
    
    
    
    //重点方法因序列化&反序列化方式没有处理ResultReceiver的全部成员变量,因此两边对象的是存在差异的
    //ResultReceiver创建方:mLocal= true mHandler = 实际设置值  mReceiver相同
    //远端ResultReceiver使用方:mLocal = false mHandler = null mReceiver相同
    //理解这两个对象的差异,对理解ResultReceiver至关重要
    public void writeToParcel(Parcel out, int flags) {
        //序列化传递时,仅传递了mReceiver 字段
        synchronized (this) {
            if (mReceiver == null) {
                mReceiver = new MyResultReceiver();
            }
            out.writeStrongBinder(mReceiver.asBinder());
        }
    }

    ResultReceiver(Parcel in) {
        //反序列化时,仅能读取到mReceiver 字段,
        mLocal = false;
        mHandler = null;
        mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder());
    }
    
    
    public static final @android.annotation.NonNull Parcelable.Creator<ResultReceiver> CREATOR
            = new Parcelable.Creator<ResultReceiver>() {
        public ResultReceiver createFromParcel(Parcel in) {
            return new ResultReceiver(in);
        }
        public ResultReceiver[] newArray(int size) {
            return new ResultReceiver[size];
        }
    };
}