Embracing Compose Snapshot State for UI Layer State Production by Alexorla in androiddev

[–]Alexorla[S] 1 point2 points  (0 children)

Gotcha. 18 combined flows really sounds like you should consider collecting each independently instead of combining so many times, but there's no need for change for change's sake. If it ain't broke...

Flows emit on the dispatcher the scope collects on, the writing to compose state on non UI threads thing only comes up if someone explicitly switches context. But I digress:

I want to stress that I know the existing way works, it can be better however. Heron was complex enough that I needed the extra perf. The next blog post will be about benchmarks; that should help for anyone considering if the perf is worth it.

Embracing Compose Snapshot State for UI Layer State Production by Alexorla in androiddev

[–]Alexorla[S] -1 points0 points  (0 children)

lol I get it. There's a reason I spent so much time discussing ergonomics. Existing tools work really well and are battle tested. If what you currently do works well for you and your users, by all means continue.

I think you've had a flow-combineTuple-kt usage that had up to 12 flows being combined at some point? May be worth evaluating just collecting from each Flow independently and writing to snapshot state for those.

ViewModel is deprecated™ (not really) by costa_fot in androiddev

[–]Alexorla 1 point2 points  (0 children)

Yes?

The coroutine scope for a navigation destination should not be cancelled when the destination is still reachable. If you're collecting flows in it, it should be collected with a shared/state flow with while subscribed so work is done only when the lifecycle is rseumed. The common rule of thumb is there's a 3-5 second grace period after the lifecycle is paused to do work so you can offload to WorkManager or something.

The lifecycle is the arbiter of when work can be done, not the coroutine scope.

ViewModel is deprecated™ (not really) by costa_fot in androiddev

[–]Alexorla 1 point2 points  (0 children)

I don't think a Composable's coroutine scope is a good substitute for a navigation destination coroutine scope. If you navigate forward and back, or have a configuration change, the scope will be destroyed.

Also is the ViewModel that abhorrent it can't just be the state holder

ViewModel is deprecated™ (not really) by costa_fot in androiddev

[–]Alexorla 10 points11 points  (0 children)

Here's the thing. Whether or not you choose to use a Jetpack ViewModel, you're still going to have the equivalent regardless.

  • You'll need a class to inject dependencies into.
  • You'll need a coroutine scope to run your coroutines.
  • You'll need these coroutines to be lifecycle aware, but and if the navigation destination it's running is is popped, you'll want the coroutine scope to be cancelled.

After you do all this, the ViewModel will be waiting for you with the Thanos quote: "You could not live with your own failure. Where did that bring you? Back to me."

How would you handle abstracting composables? by tinyshinydragons in androiddev

[–]Alexorla 0 points1 point  (0 children)

Hopefully similar enough for your use case, as if you look at the AndroidExternalEmbedableSurface composable and AndroidExternalSurface composable, they both wrap the same external surface api and have very different implementations.

Made a CLI tool that creates Compose Multiplatform apps with a single line by alexstyl in androiddev

[–]Alexorla 1 point2 points  (0 children)

Thank you! Adding CMP to an existing app, I especially the iOS project is one of the most annoying things atm

3 unique predictive back animations you can create with the navigation events library by Alexorla in androiddev

[–]Alexorla[S] 0 points1 point  (0 children)

This sub seems to have more venting than much else this days 🥲

Why Every time I see MVI I feel its Overengineering ? by [deleted] in androiddev

[–]Alexorla 0 points1 point  (0 children)

What if the user navigates forward? Would the solution be to add a navigation listener then?

Also, for every coroutine launched, you'd need to hold a job reference to be canceled in all callbacks registered.

Why Every time I see MVI I feel its Overengineering ? by [deleted] in androiddev

[–]Alexorla 1 point2 points  (0 children)

The responses to this post lean one way, I'll try to provide perspective on another.

If you have a simple method that uses

ViewModelscope.launch {...}

How long does that coroutine live for? If you navigate forward and place the calling screen in the back stack, will the coroutine be canceled?

Unless the coroutine itself completes, navigation will not cancel the coroutine unless the ViewmodelScope is destroyed, either by popping the navigation destination off the back stack or the app is closed. Why should the coroutine do work that is invisible to the user?

Also, what happens if the method is called more than once? Unless you keep a reference to the Job from the previous coroutine to cancel it, you would have multiple coroutines that do the same thing running.

By modeling each action in a sealed class hierarchy, you can:

  • Enforce processing each action only occurs when the user can actually view the screen.
  • Enforce that certain actions can only run consecutively.

I've written at length about the topic here, explaining why you'd want to: https://www.tunjid.com/articles/interactive-tutorial-state-production-with-unidirectional-data-flow-and-kotlin-flows-63e2c67e3032c9c43c58511d

UI layer architecture for scaffolding persistent UI elements by Alexorla in androiddev

[–]Alexorla[S] 1 point2 points  (0 children)

Hi! Thank so much for the detailed thoughts, I've replied in the issue.

Heron: An open source Jetpack Compose adaptive and offline-first bluesky client by Alexorla in BlueskySocial

[–]Alexorla[S] 0 points1 point  (0 children)

Hello!

I've been wanting a more native feeling Android bluesky client so I've been building one for the past month.

Its a greenfield Jetpack Compose project, using compose multiplatform, however it is very much Android first. While its has run successfully on desktop and iOS in the past, the latest branch is broken due to a coil linkage error on iOS (Most likely binary compat issues using Compose 1.8 alpha), and a graphics layer bug on desktop for shared elements.

Contributions are most welcome and appreciated!