https://kotlinlang.org logo
Title
l

Lauren Yew

09/09/2021, 11:33 PM
Hi all, coroutines & lifecycle question: If I'm launching a coroutine from an activity / presenter / view model and that coroutine is essentially going to launch a new activity flow and return a result once that flow is complete, what scope should I be launching the coroutine from? I've considered application level scope or creating a scope myself. Ideally, I'd like it to be lifecycle aware, but since I'm actually launching a new activity, I'm thinking making it lifecycle aware to a view model / activity will cancel the coroutine before I get a result back... Use case: start a login flow from different places in the app. Context: I'm trying to hook coroutines into existing legacy code that used to have rxjava + MVP architecture. There are several presenters / other code between me getting the second activity flow launch, otherwise, I would have used the onActivityResult or registerForActivityResult. The legacy code was doing this with RxJava disposables, and actually clearing the disposable with activity lifecycle, but I'm surprised that worked since the onStop() for the original activity should have been called when the new activity flow happened.
e

ephemient

09/09/2021, 11:39 PM
the Activity Result APIs are designed for getting results back from launched activities, even after stop/re-create. consider that?
1
i

Ian Lake

09/09/2021, 11:40 PM
FWIW, the Activity Result is very specifically built to always work, even through configuration changes and process death and recreation. There's no way to persist coroutines across all of those that actually works. You could have the Activity Result callback send to a Channel that you collect on, but you cannot ever assume the code that launched the activity exists at all
l

Lauren Yew

09/13/2021, 9:14 PM
I did try the activity result, but unfortunately, it's crashing b/c it requires the registration to happen on activity create, which is not what I have a the moment.
Is there a way to get around that?
i

Ian Lake

09/13/2021, 10:01 PM
You must always register ahead of time as part of your initialization, yes. That's how you get callbacks even after process death/recreation (when all of the scope associated with the one time
launch
is over and gone entirely)
☝️ 1
Of course, those Lifecycle checks only apply when you use the
ActivityResultRegistry
register
call that takes a
Lifecycle
(or the
ActivityResultCaller
convienience methods of
registerForActivityResult
, which implicitly use the
LifecycleOwner
). There's a regular
register
on
ActivityResultRegistry
if you have your own Lifecycle equivalent and are handling registering unconditionally ahead of time and unregistering as appropriately yourself (that's actually how we built the
activity-compose
API of
rememberLauncherForActivityResult
as those launchers need to be tied into Compose's hierarchy)
l

Lauren Yew

09/14/2021, 1:11 PM
Ok thanks!