VictorAlbertos / RxActivityResult

A reactive-tiny-badass-vindictive library to break with the OnActivityResult implementation as it breaks the observable chain.
Apache License 2.0
593 stars 72 forks source link

What happens if activity is destroyed #19

Closed thekalinga closed 8 years ago

thekalinga commented 8 years ago

If you launch an activity B from activity A via this library. After the launch, to claim system resources, android killed both A & holder activity, but not B (as it is the activity interacting with the user).

In this scenario

  1. You will lose reference to onResult of HolderActivity as its not persisted in the bundleonSaveInstanceState
  2. Even if you chose to save onResult during onSaveInstanceState, by the time B is done & HolderActivity is recreated, there is no guarantee you will have access to A & its subscription as activity itself is not present.

As per my understanding, as per the current implementation framework will not work as intended

VictorAlbertos commented 8 years ago

Take at look at this reference

This static variable, request, is the ultimately glue with the previous stack. Bacause this static variable holds an strong reference from the activity/fragment, it is guaranteed that the GC will not collect this reference. So, as long as Android don't kill your entire app, a valid reference should always be alive. And it does not matter if the emitted item is consumed by the recent/active activity (not recreation of the activity happened) or by the "detached/dead" (a recreation happened) but not garbaged collected previous activity, because the most recent activity/fragment is emitted along with the result. And that's the instance that you always must use (see the docs).

So, what's happen in the unlikely event that Android destroy your application while the user has started the intent but not finished.

thekalinga commented 8 years ago

Couple of problems with this approach.

  1. Since its a static reference, you can only hold one backward reference. i.e if A starts B & B starts C, HolderActivity has only reference to B, which means the reference to A is gone => A can be kicked out by Android
  2. Always have one extra activity per activityresult request to satisfy observable chain; i.e if you start activity for result in a chain 2 times, you have a total of 5 activities in the task; not 3 => more memory; more management overhead for android; more scope for the ancestor activities to be kicked out for memory
  3. Holding onto memory (static reference to previous activity) just to satisfy observable chain => not a good idea

Am open to your views

VictorAlbertos commented 8 years ago

Since its a static reference, you can only hold one backward reference. i.e if A starts B & B starts C, HolderActivity has only reference to B, which means the reference to A is gone => A can be kicked out by Android

That's perfectly fine, RxActivityResult does not need to retain any kind of reference to A, because A it is not related at all with RxActivityResult. A will be normally recreated again.

Always have one extra activity per activityresult request to satisfy observable chain; i.e if you start activity for result in a chain 2 times, you have a total of 5 activities in the task; not 3 => more memory; more management overhead for android; more scope for the ancestor activities to be kicked out for memory

To be honest, I don't know how much overhead represent the cost of this extra Activity. So far, the users of this library has not been complain regarding this matter, neither the users of my own applications.

Holding onto memory (static reference to previous activity) just to satisfy observable chain => not a good idea

There is no other way to implement this pattern.

At this point, is clearly that you should not use this library because of your concerns. In your last statement you've made it clear that in your opinion the patter used by this library is wrong. Why would you use it then?

thekalinga commented 8 years ago

That's perfectly fine, RxActivityResult does not need to retain any kind of reference to A, because A it is not related at all with RxActivityResult. A will be normally recreated again.

A should be normally recreated only if A did not start B using startActivityForResult. In my example what I forgot to mention was A startActivityForResult'ed B & B startActivityForResult'ed C using this library. So during reverse operations C should be passing back result to B & B to A, via observables

At this point, is clearly that you should not use this library because of your concerns. In your last statement you've made it clear that in your opinion the patter used by this library is wrong. Why would you use it then?

I am currently using the old school approach for many things in Android & am not happy with the callback style of Android. So, naturally I am looking for alternatives. In doing so, I look at the cost benefit analysis of using this library.

BTW, I am by no means trying downplay your effort in creating this library. I very much appreciate your effort in making this library to make Android developer friendly.

VictorAlbertos commented 8 years ago

@thekalinga I can't think on a real example of one activity which chains 2 activities results calls. In my opinion such scenario does not exist. Can you provide a real example about this?

I appreciate your concerns about RxActivityResult and the effort of sharing them with the community. But it just that it seems to me that this library is not suitable for your requirements.

VictorAlbertos commented 8 years ago

Feel free to reopen it if you want to keep discussing this issue.