起因:无意间看到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。