RxActivityResult
RxActivityResult copied to clipboard
If the screen has been closed before the second Activity back, then the first Activity will not receive a callback
##Summary If the screen has been closed before the second Activity back, then the first Activity will not receive a callback
Preconditions
#### Steps to reproduce actual result 1.
---------------------------------------------------------------------------
FirstActivity.class
RxActivityResult.on(this)
.startIntent(new Intent(this, SecondActivity.class))
.subscribe(new Action1<Result<StartActivity>>() {
@Override
public void call(Result<StartActivity> startActivityResult) {
if (startActivityResult.resultCode() == RESULT_OK) {
} else {
}
}
});
---------------------------------------------------------------------------
SecondActivity.class
//click this button and close the phone screen,the firstActivity will never receive the result
findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Observable.timer(10, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
setResult(RESULT_OK);
finish();
}
});
}
});
Actual result
#### Expected result
I add some code onResultActivity like this,it seems solved my problem
private OnResult onResultActivity() {
return new OnResult() {
@Override
public void response(final int resultCode, final Intent data) {
Observable.interval(0, 100, TimeUnit.MILLISECONDS)
.filter(new Func1<Long, Boolean>() {
@Override
public Boolean call(Long aLong) {
if (activitiesLifecycle.getLiveActivity() == null) return false;
if (activitiesLifecycle.getLiveActivity().getClass() != clazz) {
return false;
}
return true;
}
})
.observeOn(AndroidSchedulers.mainThread())
.take(1)
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
T activity = (T) activitiesLifecycle.getLiveActivity();
subject.onNext(new Result<T>((T) activity, resultCode, data));
subject.onCompleted();
}
});
}
};
}
That's very weird. Have you some dev config activated in your device? This has been tested before, actually I tested again right now and it seems to work fine. Are you using the sample project? If not, I recommend to you to test this problem taking as stating point that project.
Different mobile phone test results are the same
I write a demo https://github.com/kexuebiao/demo_activityresult/blob/master/app/src/main/java/cc/activity/activityresult/FirstActivity.java
this is the log
01-06 22:50:06.601 26087-26087/cc.activity.activityresult I/FirstActivity: onResume:
// click the FirstActivity Button
01-06 22:50:10.495 26087-26087/cc.activity.activityresult I/FirstActivity: onClick: go to second
01-06 22:50:10.556 26087-26087/cc.activity.activityresult I/FirstActivity: onPause:
01-06 22:50:10.595 26087-26087/cc.activity.activityresult I/SecondActivity: onResume:
// click the SecondActivity Button
01-06 22:50:13.560 26087-26087/cc.activity.activityresult I/SecondActivity: onClick: return
// close the phone screen
01-06 22:50:15.205 26087-26087/cc.activity.activityresult I/SecondActivity: onPause:
01-06 22:50:23.561 26087-26087/cc.activity.activityresult I/SecondActivity: SecondActivity finish
01-06 22:50:23.628 26087-26087/cc.activity.activityresult I/FirstActivity: onResume:
01-06 22:50:23.630 26087-26087/cc.activity.activityresult I/FirstActivity: onPause:
//open the phone screen after the SecondActivity finished
01-06 22:50:27.751 26087-26087/cc.activity.activityresult I/FirstActivity: onResume:
FirstActivity did not receive the message : 'call: get result from second activity'
@VictorAlbertos thanks for this library...it's clearly made our code cleaner and way more readable. However, we seem to be running into a similar issue as @kexuebiao. And more surprisingly, in our case, it is happening consistently on a particular device and not on all devices. The fix suggested by @kexuebiao above seems to fix the issue that particular device also. Would you be willing to consider accepting such a change in your code? Or do you have any suggestions on what we can try to get around the issue we are running into?
After debugging more, here's what I found. It looks like there's an assumption in the RxActivityResult code that the liveActivity will get set when onDestroyed is called for the HolderActivity. Unfortunately, on at least one particular device, this is not happening. I added logs in ActivitiesLifecycleCallbacks class, and here's the sequence that I found.
09:59:13.867 Created: com.myapp.MyActivity 09:59:13.904 Started: com.myapp.MyActivity 09:59:15.810 Resumed: com.myapp.MyActivity 09:59:20.006 Paused: com.myapp.MyActivity 09:59:20.060 Created: rx_activity_result2.HolderActivity 09:59:20.098 Started: rx_activity_result2.HolderActivity 09:59:20.106 Resumed: rx_activity_result2.HolderActivity 09:59:20.124 Paused: rx_activity_result2.HolderActivity 09:59:29.207 Stopped: rx_activity_result2.HolderActivity 09:59:29.209 Destroyed: rx_activity_result2.HolderActivity 09:59:29.233 Resumed: com.myapp.MyActivity
Because of this, when onHolderActivity is destroyed, if the onResult.response is invoked before the parent activity is resumed then there is no live activity. This is why the code added above seems to solve the problem since it effectively waits for the new activity to resume. Is there something wrong in my understanding here?
However, the code above doesn't work when using RxPaparazzo if we turn on "Don't keep activities" option in Android. In that case, when the image selection view opens, HolderActivity gets destroyed and the above response code starts running. Once image is selected and HolderActivity resumes and then gets destroyed again, another instance of that response code starts running. Depending on which one actually runs first, sometimes the code works and sometimes it doesn't.
My current workaround is to change the Observable.interval to an Observable.timer that just adds a delay to handle the issue that I noted above. But this is clearly a hack :( There ought to be better solutions than this hack.
For today android got new way working with results. The Activity Result APIs introduced in AndroidX Activity 1.2.0-alpha02 and Fragment 1.3.0-alpha02
https://developer.android.com/training/basics/intents/result
Anyone of implementations RxResult I found has this bug and it's critacal error.