使用RxJava来编写onActivityResult

起因:无意间看到AvoidOnResult,大概就是说,用类似RxPermissions的方式,将原来需要在Activity里面回调的方式改成rx的方式。
也就是说,可以直接使用像下面这样的代码来处理onActivityResult。

AvoidOnResult(this)
    .startForResult(FetchDataActivity::class.java, REQUEST_CODE_RXJAVA)
    //下面可自由变换
    .filter { it.resultCode == Activity.RESULT_OK }
    .flatMap {
        val text = it.data.getStringExtra("text")
        Observable.fromIterable(text.asIterable())
    }
    .subscribe({
        Log.d("-------> ", it.toString())
    }, {
        Toast.makeText(this, "error", Toast.LENGTH_SHORT).show()
    }, {
        Toast.makeText(this, "complete", Toast.LENGTH_SHORT).show()
    })

经过:我找了一圈README,发现并没有上传到中央仓库,然后我就把代码复制过来,自己改了改,扔到了jcenter上面。(申明:代码是复制过来的,我自己改了一部分代码之后放到了jcenter上面)。

//原来的代码
private Map<Integer, PublishSubject<ActivityResultInfo>> mSubjects = new HashMap<>();
private Map<Integer, AvoidOnResult.Callback> mCallbacks = new HashMap<>();

public Observable<ActivityResultInfo> startForResult(final Intent intent, final int requestCode) {
    PublishSubject<ActivityResultInfo> subject = PublishSubject.create();
    mSubjects.put(requestCode, subject);
    return subject.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            startActivityForResult(intent, requestCode);
        }
    });
}

public void startForResult(Intent intent, int requestCode, AvoidOnResult.Callback callback) {
    mCallbacks.put(requestCode, callback);
    startActivityForResult(intent, requestCode);
}

//修改后的代码
private PublishSubject<AResultMessage> mSubject;
private Disposable mDisposable;
private AResult.Callback mCallback;

public Observable<AResultMessage> startForResult(final Intent intent, final int requestCode) {
    mCallback = null;
    mSubject = PublishSubject.create();
    return mSubject.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            mDisposable = disposable;
            startActivityForResult(intent, requestCode);
        }
    });
}

public void startForResult(Intent intent, int requestCode, AResult.Callback callback) {
    mSubject = null;
    mCallback = callback;
    startActivityForResult(intent, requestCode);
}

@Override
public void onDetach() {
    super.onDetach();
    if (mDisposable != null && !mDisposable.isDisposed())
        mDisposable.dispose();
}

为什么不用map存储requestCode呢?其实我们可以思考一下requestCode的作用,是为了在onActivityResult的时候进行区分,但是当我们使用RxJava的方式时,已经变成一对一的回调了,所以requestCode就算去掉都没关系。所以我们完全可以像下面这样写,不用requestCode。

private AResult mResult;
mResult = new AResult(this);

//RxJava
mResult.startForResult(SecondActivity.class)
    .filter(AResultMessage::isOk)
    .map(AResultMessage::getData)
    .subscribe(it -> Log.i("AResult", it.toString()));

//Callback
mResult.startForResult(SecondActivity.class, result -> Log.i("AResult", result.toString()));

当然我也保留了传入requestCode的接口,以及所有的resultCode,requestCode,data这些返回数据。

public class AResultMessage {
    private int resultCode;
    private int requestCode;
    private Intent data;

    AResultMessage(Intent data, int resultCode, int requestCode) {
        this.data = data;
        this.resultCode = resultCode;
        this.requestCode = requestCode;
    }

    public Intent getData() {
        return data;
    }

    public int getResultCode() {
        return resultCode;
    }

    public int getRequestCode() {
        return requestCode;
    }

    public boolean isOk() {
        return resultCode == Activity.RESULT_OK;
    }

    public boolean isCancel() {
        return resultCode == Activity.RESULT_CANCELED;
    }

    public boolean isFirstUser() {
        return resultCode == Activity.RESULT_FIRST_USER;
    }

    @Override
    public String toString() {
        return "AResultMessage{" +
                "isOk=" + isOk() +
                ", isCancel=" + isCancel() +
                ", isFirstUser=" + isFirstUser() +
                ", resultCode=" + resultCode +
                ", requestCode=" + requestCode +
                ", data=" + data +
                '}';
    }
}

结果:GitHub

<dependency>
    <groupId>com.linyuzai</groupId>
    <artifactId>aresult</artifactId>
    <version>1.0.3</version>
    <type>pom</type>
</dependency>

compile 'com.linyuzai:aresult:1.0.3'

坑:在startActivityForResult()中,如果requestCode传的值小于0,那么不会回调到onActivityResult。

    原文作者:淋雨仔
    原文地址: https://www.jianshu.com/p/f5645b976796
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞