# viewmodel

Published articles for viewmodel.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Setting Up Koin in a Real Kotlin Multiplatform Project: A Step-by-Step Guide

DevFeed: [Setting Up Koin in a Real Kotlin Multiplatform Project: A Step-by-Step Guide](<https://devfeed.tech/articles/setting-up-koin-in-real-project-a-step-by-step-guide-22976.md>)

Original publisher: [Read original article](<https://blog.insert-koin.io/setting-up-koin-in-real-project-a-step-by-step-guide-1575e2357239?source=rss----925561f2ecdf---4>)

Author: Gabriel Bronzatti Moro

Published: 2026-09-07T12:01:03Z

Content type: tutorial

Language: en

Sources: [Koin developers - Medium](<https://devfeed.tech/sources/koin-developers-medium.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [compose-multiplatform](<https://devfeed.tech/topics/compose-multiplatform.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compose-multiplatform](<https://devfeed.tech/tags/compose-multiplatform.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [guide](<https://devfeed.tech/tags/guide.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [ios](<https://devfeed.tech/tags/ios.md>), [kmp](<https://devfeed.tech/tags/kmp.md>), [koin](<https://devfeed.tech/tags/koin.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [mobile-app-development](<https://devfeed.tech/tags/mobile-app-development.md>), [module](<https://devfeed.tech/tags/module.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A step-by-step tutorial for setting up Koin in a Kotlin Multiplatform project targeting Android and iOS. It covers dependencies, data, domain, and UI modules, a platform bridge, platform entry points, and dependency injection in Composables.

### Source excerpt

Hi everyone! 👋 In this article, we'll take a practical, step-by-step approach to setting up Koin in a real-world Kotlin Multiplatform (KMP) project. Instead of starting with an isolated example or a simple Hello World, we'll work with a project created by the CodandoTV community: the World Cup Best Team Simulator. The app allows users to browse football players by country and build their own dream team. It runs on both Android and iOS, using Kotlin Multiplatform for sharing business and data logic, and Compose Multiplatform to share the UI across platforms. Step 1: Add Koin Dependencies Add the Koin libraries to your version catalog: # gradle/libs.versions.toml [versions] koin = "4.2.2" [libraries] koin_core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" } koin_android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" } koin_compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" } koin_compose_viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" } In the shared module shared/build.gradle.kts, split the dependencies by source set -- commonMain gets the shared Koin libraries, androidMain gets the Android-specific one: // shared/build.gradle.kts sourceSets { commonMain.dependencies { implementation(libs.koin.core) implementation(libs.koin.compose) implementation(libs.koin.compose.viewmodel) } androidMain.dependencies { implementation(libs.koin.android) } } In the Android app module androidApp/build.gradle.kts , add the Android Koin dependency: // androidApp/build.gradle.kts dependencies { implementation(libs.koin.android) implementation(libs.koin.core) }Step 2: Create the Data Module Create shared/src/commonMain/.../data/DataModule.kt . This module provides singleton instances -- repositories, and data sources that live for the entire app lifecycle. val dataModule = module { single<WorldCupRepository> { WorldCupRepositoryImpl(ioDispatcher = Dispatchers.IO) } }Step 3: Create

## Навигация в Jetpack Compose без магии: что на самом деле делают библиотеки навигации

DevFeed: [Навигация в Jetpack Compose без магии: что на самом деле делают библиотеки навигации](<https://devfeed.tech/articles/jetpack-compose-30670.md>)

Original publisher: [Read original article](<https://habr.com/ru/companies/hh/articles/1052310/>)

Author: karenkov\_id (hh.ru)

Published: 2026-07-01T08:20:40Z

Content type: tutorial

Language: ru

Sources: [HeadHunter RU](<https://devfeed.tech/sources/headhunter-ru.md>)

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compose](<https://devfeed.tech/tags/compose.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [modo](<https://devfeed.tech/tags/modo.md>), [remembersaveable](<https://devfeed.tech/tags/remembersaveable.md>), [saveablestateholder](<https://devfeed.tech/tags/saveablestateholder.md>), [tag-08a48a9394c3](<https://devfeed.tech/tags/tag-08a48a9394c3.md>), [tag-f538878e20ff](<https://devfeed.tech/tags/tag-f538878e20ff.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article explains why naïve screen-list navigation is insufficient in Jetpack Compose and examines how the Modo navigation library addresses screen state isolation, navigation-graph persistence, lifecycle and resource cleanup, and instance stability.

### Source excerpt

Вы когда-нибудь задумывались, зачем нужны библиотеки для навигации в Jetpack Compose? Почему мы не можем просто взять mutableStateOf со списком экранов и переключаться между ними? Оказывается, если мы попробуем реализовать такой наивный подход, то столкнёмся с рядом проблем: rememberSaveable не работает, ViewModel не очищаются после ухода с экрана, Lifecycle не работает корректно и многое другое. В статье разберём, как работают библиотеки навигации в Jetpack Compose и какие задачи они решают на примере библиотеки навигации Modo. Читать далее

## Sharing ViewModels Across Android and iOS in Kotlin Multiplatform Projects

DevFeed: [Sharing ViewModels Across Android and iOS in Kotlin Multiplatform Projects](<https://devfeed.tech/articles/is-androidx-viewmodel-the-best-choice-for-kmp-projects-gustavo-fao-valvassori-38251.md>)

Original publisher: [Read original article](<https://touchlab.co/kmp-view-models>)

Published: 2026-03-02T00:00:00Z

Content type: opinion

Language: en

Sources: [Touchlab | Enterprise Mobile Innovation & Development](<https://devfeed.tech/sources/touchlab-enterprise-mobile-innovation-development.md>)

Topics: [MVVM](<https://devfeed.tech/topics/mvvm.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [compose](<https://devfeed.tech/tags/compose.md>), [design-patterns](<https://devfeed.tech/tags/design-patterns.md>), [ios](<https://devfeed.tech/tags/ios.md>), [kmp](<https://devfeed.tech/tags/kmp.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article explains the MVVM pattern and examines how sharing ViewModels across Android and iOS affects developer experience in Kotlin Multiplatform projects. It discusses separation of concerns, binders, Compose, SKIE, and Android ViewModel lifecycle behavior, including configuration changes.

### Source excerpt

Sharing ViewModels between platforms affects the iOS developer experience. In this post we will discuss this topic and some possible solutions in KMP projects that respect the native feel of iOS and Android.

## Scalable API Response Handling Across Multi-Layered Architectures with Sandwich

DevFeed: [Scalable API Response Handling Across Multi-Layered Architectures with Sandwich](<https://devfeed.tech/articles/scalable-api-response-handling-across-multi-layered-architectures-with-sandwich-25924.md>)

Original publisher: [Read original article](<https://proandroiddev.com/scalable-api-response-handling-across-multi-layered-architectures-with-sandwich-39ab02ae8c90?source=rss-9bb203a4ab2e------2>)

Author: Jaewoong Eum

Published: 2026-02-08T06:25:14Z

Content type: tutorial

Language: en

Sources: [Stories by Jaewoong Eum on Medium](<https://devfeed.tech/sources/stories-by-jaewoong-eum-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [API](<https://devfeed.tech/topics/api.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Error Handling](<https://devfeed.tech/topics/error-handling.md>), [Network](<https://devfeed.tech/topics/network.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [api](<https://devfeed.tech/tags/api.md>), [code](<https://devfeed.tech/tags/code.md>), [communication](<https://devfeed.tech/tags/communication.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [error-handling](<https://devfeed.tech/tags/error-handling.md>), [exceptions](<https://devfeed.tech/tags/exceptions.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [mvi](<https://devfeed.tech/tags/mvi.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [network](<https://devfeed.tech/tags/network.md>), [networking](<https://devfeed.tech/tags/networking.md>), [presentation](<https://devfeed.tech/tags/presentation.md>), [responses](<https://devfeed.tech/tags/responses.md>), [retrofit](<https://devfeed.tech/tags/retrofit.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to handle Retrofit API responses, errors, and exceptions across multi-layered Android architectures such as MVVM and MVI. It presents Sandwich as a type-safe, composable approach and covers response handling, composition, merging, global error mapping, and Flow integration.

### Source excerpt

Unsplash@picoftasty Modern Android applications commonly adopt multi-layered architectures such as MVVM or MVI, where data flows through distinct layers: a data source, a repository, and a ViewModel (or presentation layer). Each layer has a specific responsibility, and network responses must propagate through all of them before reaching the UI. While this separation produces clean, testable code, it introduces a real challenge: how do you handle API responses, including errors and exceptions, as they cross each layer boundary? Most developers solve this by wrapping API calls in try-catch blocks and returning fallback values. This works for small projects, but as the number of API calls grows, the approach creates ambiguous results, scattered boilerplate, and lost context that downstream layers need. You end up with ViewModels that cannot tell whether an empty list means "no data" or "network failure," repositories that swallow important error details, and data sources that repeat the same error handling pattern dozens of times. In this article, you'll explore the problems that emerge when handling Retrofit API calls across layered architectures, why conventional approaches break down at scale, and how Sandwich provides a type safe, composable solution that simplifies response handling from the network layer all the way to the UI. You'll also walk through the full set of Sandwich APIs, from basic response handling to advanced patterns like sequential composition, response merging, global error mapping, and Flow integration, each with real world use cases that show when and why you would reach for them. Retrofit API calls with coroutines Most Android projects use Retrofit with Kotlin coroutines for network communication. A typical service interface looks like this: https://medium.com/media/ebcba33386d664d1cf69a89234d2e22a/href The service returns a List<Poster> directly. Retrofit deserializes the JSON response body and gives you the data. This works perfectly when the

## Inside Jetpack ViewModel: Internal Mechanisms and Multiplatform Design

DevFeed: [Inside Jetpack ViewModel: Internal Mechanisms and Multiplatform Design](<https://devfeed.tech/articles/inside-jetpack-viewmodel-internal-mechanisms-and-multiplatform-design-25922.md>)

Original publisher: [Read original article](<https://proandroiddev.com/inside-jetpack-viewmodel-internal-mechanisms-and-multiplatform-design-2625671eaef8?source=rss-9bb203a4ab2e------2>)

Author: Jaewoong Eum

Published: 2025-12-07T02:29:08Z

Content type: tutorial

Language: en

Sources: [Stories by Jaewoong Eum on Medium](<https://devfeed.tech/sources/stories-by-jaewoong-eum-on-medium.md>)

Topics: [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [Android](<https://devfeed.tech/topics/android.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [caching](<https://devfeed.tech/tags/caching.md>), [change](<https://devfeed.tech/tags/change.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [interface](<https://devfeed.tech/tags/interface.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [key-value-store](<https://devfeed.tech/tags/key-value-store.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A technical tutorial explaining Jetpack ViewModel's internal mechanisms, including retention across configuration changes, ViewModelStore key-value caching, ViewModelProvider creation, factory-based instantiation, resource cleanup, and coroutine integration.

### Source excerpt

Unsplash@davidvig Jetpack's ViewModel has become an essential component of modern Android development, providing a lifecycle-aware container for UI-related data that survives configuration changes. While the API appears simple on the surface, the internal machinery reveals design decisions around lifecycle management, multiplatform abstraction, resource cleanup, and thread-safe caching. Understanding how ViewModel works under the hood helps you make better architectural decisions and avoid subtle bugs. In this article, you'll dive deep into how Jetpack ViewModel works internally, exploring how the ViewModelStore retains instances across configuration changes, how ViewModelProvider orchestrates creation and caching, how the factory pattern enables flexible instantiation, how CreationExtras enables stateless factories, how resource cleanup is managed through the Closeable pattern, and how viewModelScope integrates coroutines with the ViewModel lifecycle. The fundamental problem: Surviving configuration changes Configuration changes present a fundamental challenge for Android development. When a user rotates their device, changes language settings, or triggers any configuration change, the system destroys and recreates the Activity. Any data stored in the Activity is lost: https://medium.com/media/82ee86f042e31a1ede3f551f919b4429/href The naive approach is to use onSaveInstanceState(): https://medium.com/media/74f2c1da669e831b1488b3f297d55997/href This works for small, serializable data. But what about large datasets, network connections, or objects that can't be serialized? What about ongoing operations like network requests? The Bundle approach fails for these cases, both because of size limitations and because serialization/deserialization is expensive. ViewModel solves this by providing a lifecycle-aware container that survives configuration changes through a retained object pattern, not serialization. The ViewModelStore: The retention mechanism At the heart of Vie

## Android ViewModel Data Loading: Best Practices and Flow-Based Architecture

DevFeed: [Android ViewModel Data Loading: Best Practices and Flow-Based Architecture](<https://devfeed.tech/articles/android-viewmodel-data-loading-best-practices-and-flow-based-architecture-22967.md>)

Original publisher: [Read original article](<https://funkymuse.github.io/posts/properly-load-data/>)

Author: FunkyMuse

Published: 2025-08-28T23:11:00Z

Content type: opinion

Language: en

Sources: [FunkyMuse](<https://devfeed.tech/sources/funkymuse.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Development](<https://devfeed.tech/topics/development.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [compose](<https://devfeed.tech/tags/compose.md>), [development](<https://devfeed.tech/tags/development.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [mvi](<https://devfeed.tech/tags/mvi.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [patterns](<https://devfeed.tech/tags/patterns.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

An opinionated Android architecture article examines data-loading patterns in ViewModels and discusses problems associated with loading data in initialization blocks, including re-entry behavior, dispatcher timing, data freshness, and testability. It presents Kotlin Flow and StateFlow sharing as the proposed solution.

### Source excerpt

Architecture discussions in Android development often spark passionate debates--sometimes garnering both praise and criticism. Writing about these topics isn't easy, but that's what makes it worthwhile. This article presents my opinionated perspective on data loading patterns, refined through experience and recovery from recent surgeries (one recovery is still in progress). Consider this a sna...

## JSX Over The Wire

DevFeed: [JSX Over The Wire](<https://devfeed.tech/articles/jsx-over-the-wire-36177.md>)

Original publisher: [Read original article](<https://overreacted.io/jsx-over-the-wire/>)

Published: 2025-04-16T00:00:00Z

Content type: article

Language: en

Sources: [Dan Abramov](<https://devfeed.tech/sources/dan-abramov.md>)

Topics: [React](<https://devfeed.tech/topics/react.md>), [API](<https://devfeed.tech/topics/api.md>), [React Component](<https://devfeed.tech/topics/react-component.md>), [Database](<https://devfeed.tech/topics/database.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [database](<https://devfeed.tech/tags/database.md>), [react](<https://devfeed.tech/tags/react.md>), [react-component](<https://devfeed.tech/tags/react-component.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

The article explores an inside-out approach in which an API returns React components or JSX rather than only JSON data. It then examines the difference between raw Models stored in databases and personalized, aggregated ViewModels consumed by a UI.

### Source excerpt

Turning your API inside-out.

## Bridging Compose and View: Seamless Interop Communication with CompositionLocal

DevFeed: [Bridging Compose and View: Seamless Interop Communication with CompositionLocal](<https://devfeed.tech/articles/bridging-compose-and-view-seamless-interop-communication-with-compositionlocal-25937.md>)

Original publisher: [Read original article](<https://juliensalvi.medium.com/bridging-compose-and-view-seamless-interop-communication-with-compositionlocal-4b0a273bf15f?source=rss-cbfc736ddcd3------2>)

Author: Julien Salvi

Published: 2025-03-05T13:42:13Z

Content type: tutorial

Language: en

Sources: [Stories by Julien Salvi on Medium](<https://devfeed.tech/sources/stories-by-julien-salvi-on-medium.md>)

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [interoperability](<https://devfeed.tech/topics/interoperability.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [bridge](<https://devfeed.tech/tags/bridge.md>), [compose](<https://devfeed.tech/tags/compose.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [interface-implementation](<https://devfeed.tech/tags/interface-implementation.md>), [interoperability](<https://devfeed.tech/tags/interoperability.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to bridge Jetpack Compose and traditional Android Views using CompositionLocal. It shows how to provide a FeedbackMessageInterop implementation so composables can trigger View-based feedback, and describes the reverse direction through an interface and reactive streams such as StateFlow or SharedFlow.

### Source excerpt

Migrating to Compose exposed the team to several interoperability challenges as we integrated new Composables into our existing codebase. One key hurdle was figuring out how to trigger events from Compose and dispatch them to the main View holder, such as a Fragment or Activity. After some exploration, we found an efficient solution using CompositionLocal. Here's how we made it work! 🚀 What is a CompositionLocal? Think of CompositionLocal as a localized dependency injection system built directly into Compose's composition model. You create a CompositionLocal instance, which acts as a key for a specific type of data. Then, using the CompositionLocalProvider, you define a scope within your UI tree and associate a value with that CompositionLocal key. Any composable within that scope can then access the provided value using the CompositionLocal.current property, without needing to know where the value originated. This not only simplifies code but also makes it more maintainable and reusable. Furthermore, CompositionLocal values can be dynamic, triggering recomposition when they change, and they are thread-safe, making them a powerful tool for managing shared state within your Compose UI. Interop Communication with CompositionLocal In the following code, LocalFeedbackInterop is a staticCompositionLocalOf that will hold an implementation of the FeedbackMessageInterop interface. This interface defines the methods for showing feedback alerts, and the staticCompositionLocalOf ensures that the implementation is unlikely to change as it cannot be re-provided. This allows any composable within the scope to access the FeedbackMessageInterop implementation and trigger feedback messages without explicit dependencies. import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf val LocalFeedbackInterop: ProvidableCompositionLocal<FeedbackMessageInterop?> = staticCompositionLocalOf { null } interface FeedbackMessageInterop { fu

## Representing ViewModel events with StateFlow vs. SharedFlow vs. Channel

DevFeed: [Representing ViewModel events with StateFlow vs. SharedFlow vs. Channel](<https://devfeed.tech/articles/representing-viewmodel-events-with-stateflow-vs-sharedflow-vs-channel-39393.md>)

Original publisher: [Read original article](<https://kt.academy/article/viewmodel-stateflow-sharedflow-channel>)

Published: 2024-11-18T00:00:00Z

Content type: tutorial

Language: en

Sources: [Kt. Academy](<https://devfeed.tech/sources/kt-academy.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [channel](<https://devfeed.tech/tags/channel.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [toast](<https://devfeed.tech/tags/toast.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

This article compares StateFlow, SharedFlow, and Channel for representing events in an Android ViewModel. It explains why StateFlow can lose events, notes SharedFlow's behavior when no UI observer is present, and discusses using an unlimited-capacity Channel as an event queue.

### Source excerpt

What is the best way to represent ViewModel events in Kotlin?

## Coroutine Testing - Never ending tests & backgroundScope

DevFeed: [Coroutine Testing - Never ending tests & backgroundScope](<https://devfeed.tech/articles/coroutine-testing-never-ending-tests-backgroundscope-25236.md>)

Original publisher: [Read original article](<https://kau.sh/blog/coroutine-testing-backgroundscope/>)

Author: Kaushik Gopal

Published: 2024-08-30T07:00:45Z

Content type: tutorial

Language: en

Sources: [Kaushik Gopal's Site](<https://devfeed.tech/sources/kaushik-gopal-s-site.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Unit testing](<https://devfeed.tech/topics/unit-testing.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Android](<https://devfeed.tech/topics/android.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [channel](<https://devfeed.tech/tags/channel.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutine-testing](<https://devfeed.tech/tags/coroutine-testing.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [job](<https://devfeed.tech/tags/job.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [testing](<https://devfeed.tech/tags/testing.md>), [tests](<https://devfeed.tech/tags/tests.md>), [unit-testing](<https://devfeed.tech/tags/unit-testing.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains why coroutine tests can time out when they collect from non-terminating Channels, SharedFlow, StateFlow, or ViewModel jobs. It presents manual Job cancellation and backgroundScope, which cancels child coroutines when the test body completes.

### Source excerpt

series This is part of a series of posts on Coroutine Testing: Picking the right Dispatcher Never ending tests & backgroundscope <- Controlling time Helpful @Junit TestRule extension (coming soon) Full USF example for Android (coming soon) If you've spent some time testing Coroutines this exception should look familiar: After waiting for 1m, the test coroutine is not completing, there were active child jobs This tends to happen when you have a coroutine job in your test, that fails to complete on its own. Let's take a simple example. src on github We use a Channel here which is the proverbial event bus for Coroutines. source: kotlinlang.org Channels don't terminate on their own. So when you run a simple test checking the emission, while the items might get collected correctly per the assert statement in the test, the test itself fails like so: test on github The test here is waiting for that coroutine job to complete, which in turn requires the Channel to, but that never happens and the test times out. Where else would I run into this problem? # Channels aren't the only case you'll run into this problem. For example if you use a "hot" Flow like SharedFlow or StateFlow, they don't terminate on their own, so the onus is on you to complete or cancel their Job in tests. Android developers can frequently run into this problem too if you use ViewModels and have an internal StateFlow providing your "view level data" (what i personally like to call "view state"). You typically use the viewModelScope to launch internal coroutine jobs in a ViewModel. The OS then calls the lifecycle method onClear when the Activity or Fragment no longer needs the ViewModel where all jobs started in the viewModelScope are canceled. But when unit testing these ViewModels, you don't have access to the viewModelScope and shouldn't need it anyway. Solving this problem # There's two ways to solve this problem: 1. Manually cancel the Job ## If you have access to the Job that spawns the never-ending co

## Android Jetpack ViewModel has KMP Support! - Kevin Schildhorn

DevFeed: [Android Jetpack ViewModel has KMP Support! - Kevin Schildhorn](<https://devfeed.tech/articles/android-jetpack-viewmodel-has-kmp-support-kevin-schildhorn-38252.md>)

Original publisher: [Read original article](<https://touchlab.co/kmp-viewmodel>)

Published: 2024-03-22T00:00:00Z

Content type: article

Language: en

Sources: [Touchlab | Enterprise Mobile Innovation & Development](<https://devfeed.tech/sources/touchlab-enterprise-mobile-innovation-development.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [Library](<https://devfeed.tech/topics/library.md>), [version](<https://devfeed.tech/topics/version.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-jetpack](<https://devfeed.tech/tags/android-jetpack.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [ios](<https://devfeed.tech/tags/ios.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kmp](<https://devfeed.tech/tags/kmp.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [library](<https://devfeed.tech/tags/library.md>), [version](<https://devfeed.tech/tags/version.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

The lifecycle-viewmodel artifact, part of Android Jetpack, adds Kotlin Multiplatform support in version 2.8.0-alpha03. ViewModel and related classes can be used from common code, with guidance on adding the dependency and handling possible duplicate-class conflicts with Jetpack Compose.

### Source excerpt

This article discusses the newest version of the lifecycle-viewmodel artifact, part of the official Android Jetpack library, and how it adds support for KMP projects.

## Crash course on the Android UI layer | Part 2

DevFeed: [Crash course on the Android UI layer | Part 2](<https://devfeed.tech/articles/crash-course-on-the-android-ui-layer-part-2-22599.md>)

Original publisher: [Read original article](<https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-2-2335171467e0?source=rss----6353b5325b1a---4>)

Author: Manuel Vivo

Published: 2023-12-19T15:58:45Z

Content type: tutorial

Language: en

Sources: [Bumble Tech](<https://devfeed.tech/sources/bumble-tech.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [business logic](<https://devfeed.tech/topics/business-logic.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [navigation](<https://devfeed.tech/topics/navigation.md>), [data](<https://devfeed.tech/topics/data.md>), [Requirements](<https://devfeed.tech/topics/requirements.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [apis](<https://devfeed.tech/tags/apis.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [best-practices](<https://devfeed.tech/tags/best-practices.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [requirements](<https://devfeed.tech/tags/requirements.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

Part 2 of a series on the Android UI layer explains state holders, saving UI state, state hoisting, and the distinction between business logic and UI logic. It describes how these types of logic should respond to configuration changes.

### Source excerpt

Crash Course on the Android UI Layer | Part 2State Holders and Saving State This blog post series aims to summarise the Android Developer guidance on the UI layer. We'll explore all the entities involved in it, understand the role each part plays, and discuss best practices. By the end of this series, you will have a general understanding of what happens on the UI layer and how to best handle state and logic within it, the various APIs involved, and how to use them. Additionally, we'll provide decision trees to assist you when you're in doubt. In part 1, we covered the UI and the UI state. You should already know the different entities present on the UI layer, and how to think about the UI and UI state effectively. Crash course on the Android UI layer | Part 1 Now it's time for Part 2! We'll cover state holders and other UI layer-related topics such as where to hoist state and save UI state on Android. If you prefer to consume this content in video format, check out the talk I delivered at Droidcon London 2023: Peeling Back the Layers: Unmasking the UI-nknown! State holders State holders simplify the UI by handling logic and/or exposing UI state. In this section, we'll see how to implement state holders and the implementation details to consider. To determine the implementation details, we first need to identify the types of logic commonly found in an Android app. Types of logic We have already discussed that business logic involves implementing the product requirements that specify how application data is created, stored, and modified. When business logic is present in the UI layer, it's recommended to manage this logic at the screen level. We'll see more of this later. Another type of logic is the UI logic. UI logic determines how to display state changes on the screen. While business logic dictates what to do with data, UI logic determines how to visually display it. The UI logic is dependent on the UI configuration. For instance, in a typical app, displaying a d

## Crash course on the Android UI layer | Part 1

DevFeed: [Crash course on the Android UI layer | Part 1](<https://devfeed.tech/articles/crash-course-on-the-android-ui-layer-part-1-22598.md>)

Original publisher: [Read original article](<https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-1-2094221a9be3?source=rss----6353b5325b1a---4>)

Author: Manuel Vivo

Published: 2023-12-13T17:03:40Z

Content type: tutorial

Language: en

Sources: [Bumble Tech](<https://devfeed.tech/sources/bumble-tech.md>)

Topics: [ui](<https://devfeed.tech/topics/ui.md>), [Android](<https://devfeed.tech/topics/android.md>), [business logic](<https://devfeed.tech/topics/business-logic.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [app-architecture](<https://devfeed.tech/tags/app-architecture.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [best-practices](<https://devfeed.tech/tags/best-practices.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [state-management](<https://devfeed.tech/tags/state-management.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

Part 1 of a series explains the Android UI layer, UI state, and the roles of the UI, data, and optional domain layers. It introduces separation of concerns, state holders, unidirectional data flow, and related best practices.

### Source excerpt

Crash Course on the Android UI Layer | Part 1The UI and UI State This blog post series aims to summarise the Android Developer guidance on the UI layer. We'll explore all the entities involved in it, understand the role each part plays, and discuss best practices. By the end of this series, you will have a general understanding of what happens on the UI layer and how to best handle state and logic within it, the various APIs involved, and how to use them. Additionally, we'll provide decision trees to assist you when you're in doubt. This is part 1, where we're covering the UI and the UI state. Part 2 covers state holders and other UI layer-related topics such as where to hoist state and save state on Android. If you prefer to consume this content in video format, check out the talk I delivered at Droidcon London 2023: Peeling Back the Layers: Unmasking the UI-nknown! The UI layer in the grand scheme of things The UI layer isn't the only layer you can find in a typical app architecture. Alongside it, you can also find the data layer and sometimes, the domain layer. According to the Android Architecture documentation: The UI layer displays data on the screen. The data layer exposes application data and contains the vast majority of the business logic of the app. The domain layer is an optional layer that aims to 1) simplify and 2) reuse the potential business logic complexity of the UI layer. No less, no more. Note: The business logic is what gives value to your application. It's the implementation of product requirements that determines how your app fetches, stores, and modifies data.Architecture layers in a typical Android app: The UI, data, and domain layersEntities in the UI layer The UI layer consists of three distinct entities with clearly defined responsibilities. This distinction helps with separation of concerns, enhances testability, and promotes reusability. The UI, or UI elements, render data on the screen. The UI state describes the data to render on the

## The conflation problem of testing StateFlows

DevFeed: [The conflation problem of testing StateFlows](<https://devfeed.tech/articles/the-conflation-problem-of-testing-stateflows-27057.md>)

Original publisher: [Read original article](<https://zsmb.co/conflating-stateflows/>)

Author: Márton Braun

Published: 2023-08-15T14:00:00Z

Content type: tutorial

Language: en

Sources: [zsmb.co](<https://devfeed.tech/sources/zsmb-co.md>)

Topics: [Testing](<https://devfeed.tech/topics/testing.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [coroutine-testing](<https://devfeed.tech/tags/coroutine-testing.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinx](<https://devfeed.tech/tags/kotlinx.md>), [marton-braun](<https://devfeed.tech/tags/marton-braun.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [testing](<https://devfeed.tech/tags/testing.md>), [tests](<https://devfeed.tech/tags/tests.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [zsmb](<https://devfeed.tech/tags/zsmb.md>), [zsmb-co](<https://devfeed.tech/tags/zsmb-co.md>), [zsmb13](<https://devfeed.tech/tags/zsmb13.md>), [zsmbco](<https://devfeed.tech/tags/zsmbco.md>)

### AI overview

This article explains how StateFlow conflation affects tests. It compares asserting on the StateFlow state property with collecting emitted values, and discusses testing intermediate values when rapid updates may be skipped by slow collectors.

### Source excerpt

StateFlow behaves as a state holder and a Flow of values at the same time. Due to conflation, a collector of a StateFlow might not receive all values that it holds over time. This article covers what that means for your tests.

## ViewModels in Jetpack Compose: Their Uses, Alternatives, and Setup

DevFeed: [ViewModels in Jetpack Compose: Their Uses, Alternatives, and Setup](<https://devfeed.tech/articles/why-you-need-viewmodels-and-why-you-don-t-28461.md>)

Original publisher: [Read original article](<https://composables.com/blog/viewmodels-in-jetpack-compose>)

Author: Alex Styl

Published: 2023-05-13T00:00:00Z

Content type: tutorial

Language: en

Sources: [Composables - Concise, no-fluff video tutorials for Android developers](<https://devfeed.tech/sources/composables-concise-no-fluff-video-tutorials-for-android-developers.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [API](<https://devfeed.tech/topics/api.md>), [business logic](<https://devfeed.tech/topics/business-logic.md>), [Architecture & Design](<https://devfeed.tech/topics/architecture-design.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Library](<https://devfeed.tech/topics/library.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [api](<https://devfeed.tech/tags/api.md>), [architecture-design](<https://devfeed.tech/tags/architecture-design.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [tutorial](<https://devfeed.tech/tags/tutorial.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A tutorial explaining Android ViewModels in Jetpack Compose, including how they preserve data across configuration changes, hold UI-related business logic, and emit updated state. It also discusses when ViewModels may not be necessary, alternatives outside Android, and the dependencies used to access them in composables.

### Source excerpt

Everything you need to know about ViewModels in Jetpack Compose

## StateFlow and SharedFlow in ViewModels

DevFeed: [StateFlow and SharedFlow in ViewModels](<https://devfeed.tech/articles/stateflow-and-sharedflow-in-viewmodels-22664.md>)

Original publisher: [Read original article](<https://www.valueof.io/blog/stateflow-sharedflow-flow-viewmodel-lifecycle>)

Author: James Shvarts

Published: 2022-12-28T19:21:19Z

Content type: tutorial

Language: en

Sources: [Android Blog - Mobile Dev Notes](<https://devfeed.tech/sources/android-blog-mobile-dev-notes.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [Code](<https://devfeed.tech/topics/code.md>), [Unit testing](<https://devfeed.tech/topics/unit-testing.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compose](<https://devfeed.tech/tags/compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [unit-testing](<https://devfeed.tech/tags/unit-testing.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A practical guide to choosing between StateFlow and SharedFlow in Android ViewModels. It covers lifecycle-aware collection, exposing flows as UI state in view-based apps and Compose, and unit testing ViewModels that convert flows into state or shared events.

### Source excerpt

Collecting State and Shared Flows from ViewModels while respecting lifecycle of the collector views

## Basic Auth with OkHttp and Retrofit

DevFeed: [Basic Auth with OkHttp and Retrofit](<https://devfeed.tech/articles/basic-auth-with-okhttp-and-retrofit-22649.md>)

Original publisher: [Read original article](<https://www.valueof.io/blog/basic-auth-okhttp-retrofit-dagger>)

Author: James Shvarts

Published: 2022-11-05T22:25:12Z

Content type: tutorial

Language: en

Sources: [Android Blog - Mobile Dev Notes](<https://devfeed.tech/sources/android-blog-mobile-dev-notes.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [HTTP](<https://devfeed.tech/topics/http.md>), [API](<https://devfeed.tech/topics/api.md>), [Dagger](<https://devfeed.tech/topics/dagger.md>), [Library](<https://devfeed.tech/topics/library.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [api](<https://devfeed.tech/tags/api.md>), [auth](<https://devfeed.tech/tags/auth.md>), [authentication](<https://devfeed.tech/tags/authentication.md>), [dagger-hilt](<https://devfeed.tech/tags/dagger-hilt.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [http](<https://devfeed.tech/tags/http.md>), [json](<https://devfeed.tech/tags/json.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [libraries](<https://devfeed.tech/tags/libraries.md>), [payload](<https://devfeed.tech/tags/payload.md>), [request](<https://devfeed.tech/tags/request.md>), [retrofit](<https://devfeed.tech/tags/retrofit.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A tutorial showing how to perform authenticated HTTP GET requests in a Kotlin Android project using Basic Authentication with OkHttp, Retrofit, Dagger/Hilt, and Moshi.

### Source excerpt

Basic Auth example using OkHttp, Retrofit, Dagger in a Kotlin project

## State holders and state production in the UI Layer

DevFeed: [State holders and state production in the UI Layer](<https://devfeed.tech/articles/state-holders-and-state-production-in-the-ui-layer-35679.md>)

Original publisher: [Read original article](<https://manuelvivo.dev/state-holders-ui-layer>)

Author: Manuel Vivo

Published: 2022-10-25T00:00:01Z

Content type: tutorial

Language: en

Sources: [Manuel Vivo .dev](<https://devfeed.tech/sources/manuel-vivo-dev.md>)

Topics: [ui](<https://devfeed.tech/topics/ui.md>), [LineageOS](<https://devfeed.tech/topics/lineageos.md>), [Development](<https://devfeed.tech/topics/development.md>), [business logic](<https://devfeed.tech/topics/business-logic.md>), [screen](<https://devfeed.tech/topics/screen.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [dev](<https://devfeed.tech/tags/dev.md>), [screen](<https://devfeed.tech/tags/screen.md>), [state](<https://devfeed.tech/tags/state.md>), [talk](<https://devfeed.tech/tags/talk.md>), [talks](<https://devfeed.tech/tags/talks.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

An Android Dev Summit 2022 talk about producing UI state and managing UI complexity with state holders. It explains the differences between UI and business logic, ViewModels and plain state holder classes, and state versus events.

### Source excerpt

Android Dev Summit 2022 talk

## Using an Activity from a Hilt ViewModel

DevFeed: [Using an Activity from a Hilt ViewModel](<https://devfeed.tech/articles/using-an-activity-from-a-hilt-viewmodel-25634.md>)

Original publisher: [Read original article](<https://blog.p-y.wtf/using-an-activity-from-a-hilt-viewmodel>)

Author: Pierre-Yves Ricau

Published: 2022-09-07T21:59:49Z

Content type: tutorial

Language: en

Sources: [Py's blog](<https://devfeed.tech/sources/py-s-blog.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [blog](<https://devfeed.tech/tags/blog.md>), [code](<https://devfeed.tech/tags/code.md>), [component](<https://devfeed.tech/tags/component.md>), [dagger-hilt](<https://devfeed.tech/tags/dagger-hilt.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [state](<https://devfeed.tech/tags/state.md>), [view](<https://devfeed.tech/tags/view.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial presents a Hilt-based technique for accessing the current Android Activity from a Hilt ViewModel. It uses scoped activity storage, an activity-scoped entry point, and lifecycle callbacks to update the reference while accounting for configuration changes and multiple activities.

### Source excerpt

👋 Hi, this is P.Y., I work as an Android Engineer at Block. This blog shares a bit of hackery to be able to access an activity instance within a Hilt ViewModel. If you come up with other interesting

## Consuming flows safely in Jetpack Compose

DevFeed: [Consuming flows safely in Jetpack Compose](<https://devfeed.tech/articles/consuming-flows-safely-in-jetpack-compose-35672.md>)

Original publisher: [Read original article](<https://manuelvivo.dev/consuming-flows-compose>)

Author: Manuel Vivo

Published: 2022-08-10T00:00:00Z

Content type: tutorial

Language: en

Sources: [Manuel Vivo .dev](<https://devfeed.tech/sources/manuel-vivo-dev.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [API](<https://devfeed.tech/topics/api.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [function](<https://devfeed.tech/topics/function.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Boilerplate](<https://devfeed.tech/topics/boilerplate.md>), [now-in-android](<https://devfeed.tech/topics/now-in-android.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [boilerplate](<https://devfeed.tech/tags/boilerplate.md>), [compose](<https://devfeed.tech/tags/compose.md>), [flow](<https://devfeed.tech/tags/flow.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [now-in-android](<https://devfeed.tech/tags/now-in-android.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to use collectAsStateWithLifecycle in Jetpack Compose to collect Flow and StateFlow values from UI code in a lifecycle-aware way. It describes how collection follows the app lifecycle, stops by default when the app is in the background, and helps avoid unnecessary resource usage. The API is identified as alpha and requires opting in to its annotation.

### Source excerpt

Use the collectAsStateWithLifecycle API to collect flows in a lifecycle-aware manner from your UI.

## Improving shared architecture for a Kotlin Multiplatform, Jetpack Compose and SwiftUI app

DevFeed: [Improving shared architecture for a Kotlin Multiplatform, Jetpack Compose and SwiftUI app](<https://devfeed.tech/articles/improving-shared-architecture-for-a-kotlin-multiplatform-jetpack-compose-and-swiftui-app-25566.md>)

Original publisher: [Read original article](<https://www.marcogomiero.com/posts/2022/improved-kmm-shared-app-arch/>)

Author: Marco Gomiero

Published: 2022-06-26T00:00:00Z

Content type: tutorial

Language: en

Sources: [Posts on Marco Gomiero](<https://devfeed.tech/sources/posts-on-marco-gomiero.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [SwiftUI](<https://devfeed.tech/topics/swiftui.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-jetpack](<https://devfeed.tech/tags/android-jetpack.md>), [app](<https://devfeed.tech/tags/app.md>), [app-architecture](<https://devfeed.tech/tags/app-architecture.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [article](<https://devfeed.tech/tags/article.md>), [compose](<https://devfeed.tech/tags/compose.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [ios](<https://devfeed.tech/tags/ios.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [swiftui](<https://devfeed.tech/tags/swiftui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to improve a shared application architecture for Kotlin Multiplatform, Jetpack Compose, and SwiftUI. It replaces duplicated suspendable and non-suspendable methods plus platform-specific callbacks with Kotlin and Swift wrapper code that allows Swift to consume Kotlin Flow, enabling a single UseCase method that returns a Flow.

### Source excerpt

A couple of years ago I started working on a pet project to manage personal finances, named MoneyFlow. This project soon became a personal playground for a Kotlin Multiplatform mobile app and in a previous article, I journaled all the steps that lead me to a satisfying (at least for that time) shared app architecture. Choosing the right architecture for a [new] Kotlin Multiplatform, Jetpack Compose and SwiftUI app

## Making reusable composables using Generics

DevFeed: [Making reusable composables using Generics](<https://devfeed.tech/articles/making-reusable-composables-using-generics-22651.md>)

Original publisher: [Read original article](<https://www.valueof.io/blog/compose-composable-function-generics>)

Author: James Shvarts

Published: 2022-04-29T20:02:08Z

Content type: tutorial

Language: en

Sources: [Android Blog - Mobile Dev Notes](<https://devfeed.tech/sources/android-blog-mobile-dev-notes.md>)

Topics: [generics](<https://devfeed.tech/topics/generics.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [Java](<https://devfeed.tech/topics/java.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>)

Tags: [component](<https://devfeed.tech/tags/component.md>), [compose](<https://devfeed.tech/tags/compose.md>), [dialog](<https://devfeed.tech/tags/dialog.md>), [generics](<https://devfeed.tech/tags/generics.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial shows how to use Java Generics with Jetpack Compose to build reusable composable components that support different model objects. It demonstrates a shared delete-confirmation dialog, call sites, optional properties, and state handling in a ViewModel.

### Source excerpt

Using Java Generics to create reusable shared components in Compose

## Video playback in LazyColumn in Jetpack Compose

DevFeed: [Video playback in LazyColumn in Jetpack Compose](<https://devfeed.tech/articles/video-playback-in-lazycolumn-in-jetpack-compose-25900.md>)

Original publisher: [Read original article](<https://proandroiddev.com/video-playback-in-lazycolumn-in-jetpack-compose-df355097f26e?source=rss-56174fa84bcc------2>)

Author: Denys Rudenko

Published: 2021-10-05T23:51:23Z

Content type: tutorial

Language: en

Sources: [Stories by Denis Rudenko on Medium](<https://devfeed.tech/sources/stories-by-denis-rudenko-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [ExoPlayer](<https://devfeed.tech/topics/exoplayer.md>), [Playback](<https://devfeed.tech/topics/playback.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [article](<https://devfeed.tech/tags/article.md>), [compose](<https://devfeed.tech/tags/compose.md>), [exoplayer](<https://devfeed.tech/tags/exoplayer.md>), [image](<https://devfeed.tech/tags/image.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [playback](<https://devfeed.tech/tags/playback.md>), [state](<https://devfeed.tech/tags/state.md>), [video](<https://devfeed.tech/tags/video.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A tutorial on implementing manual and automatic video playback in a Jetpack Compose LazyColumn using ExoPlayer. It covers preserving playback positions, pausing videos when cards are not visible, and responding to the application lifecycle.

### Source excerpt

Article will cover both manual & auto-playback of videos in an efficient way, storing/restoring last played video position, pausing playback if video card is not visible to the user and handling application lifecycle. ExoPlayer will be used for video playback, and these videos as a test data set. Coil will be used for displaying the video thumbnails. Video shows manual play/pause & auto-playback versions side to side. https://medium.com/media/98ab3ea482f78b96bf44de2ce54c7168/hrefStep 1: VideosScreen Let's start implementing all of those features step by step. First we create a composable which will contain the exoPlayer instance, list of videos and playingItemIndex: https://medium.com/media/2440139ad1f185b8d1f1446f844530b9/href Very important part here is using keys for the lazyColumn. In short: we provide a key which enables item state to be consistent across data-set changes isPlaying -- we can always know if video is playing or not. If it's playing -- playingItemIndex will represent the position of the item in the list, if nothing is playing -- null. We need this field to know if we should show play/pause icon, and thumbnail image or playerView. VideoCard -- composable which exposes click event on play/pause icon. Click will be handled inside the viewModel. Notice that we're passing current playback position from exoPlayer as well as the index of clicked item. We'll use it to save & restore the playback position for each video. https://medium.com/media/518600644bbec8f225a0c4b933adccd1/href Whenever the play/pause icon is clicked, we're checking for three scenarios: currentlyPlayingIndex is null -- video is not playing at the moment, so we are assigning the videoIndex to currentlyPlayingIndex. currentlyPlayingIndex is the same as videoIndex clicked -- this means that the same video is already playing, and we want to pause the playback. That's why we assign null to currentlyPlayingIndex. To store the last played video position we're mutating list, and saving the position

## Safely collecting hot flows from Android native UI

DevFeed: [Safely collecting hot flows from Android native UI](<https://devfeed.tech/articles/safely-collecting-hot-flows-from-android-native-ui-25910.md>)

Original publisher: [Read original article](<https://chao2zhang.medium.com/safely-collecting-hot-flows-from-android-native-ui-f22f645edb44?source=rss-d19045640fe------2>)

Author: Chao Zhang

Published: 2021-09-02T23:38:42Z

Content type: tutorial

Language: en

Sources: [Stories by Chao Zhang on Medium](<https://devfeed.tech/sources/stories-by-chao-zhang-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [XML](<https://devfeed.tech/topics/xml.md>), [data](<https://devfeed.tech/topics/data.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [bug](<https://devfeed.tech/tags/bug.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [flow](<https://devfeed.tech/tags/flow.md>), [issue](<https://devfeed.tech/tags/issue.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [native](<https://devfeed.tech/tags/native.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

This tutorial explains a common Android UI pitfall when collecting multiple hot flows in one coroutine. Because StateFlow never completes, a later collection may never execute; the article presents separate coroutines and flowWithLifecycle() as fixes.

### Source excerpt

Photo: Merlene Goulet from Unsplash Along with the coroutine adoption, StateFlowbecomes an alternative observable data holder for LiveDatasince StateFlowhas almost all the functionalities of LiveDatawithout the main thread confinment. On top of following the best practice of the safer way to collect flows from Android UI, this story covers another common pitfall in detail. Setup I would like to display 2 text views and 1 button: First text view: Display a number X. Second text view: Display X² reactively. Button: Upon click, increments the number X. Apologize for the Jetpack Compose fans, I am still going to define the layout in XML with ViewBinding. https://medium.com/media/b411ff48ddf74bafb4288a430f431a87/href The data structure can be defined in the ViewModel : https://medium.com/media/3d3b345797521dd3063498c538d0715c/href To subscribe to these flows in the activity, I would use lifecycleScope.launchX to collect them, just like collecting LiveData in the old days: https://medium.com/media/4db49b992c028c1be26235e17d232d49/hrefBug When I run the app, I am expecting to see that every time I click the button, both text views will be updated, the first one with the new X and the second one with the new X². Let's run the app and see! What is happening? Why is the second text view not showing X²? Cause Reading the documentation of StateFlow , there is an important piece of information: State flow never completes. From the implementation side, StateFlowImpl has a while(true) loop that does not exit normally. Since we are subscribing a hot flow sourceFlowin the coroutine, the subsequent operations inside the coroutine will not ever be executed. lifecycleScope.launchWhenResumed { viewModel.sourceFlow.collect { binding.sourceFlow.text = it.toString() // Execution stops here } viewModel.transformedFlow.collect { binding.transformedFlow.text = it.toString() } } Note that if the upstream flow does not complete, the downstream flow does not complete either. In our case, sinkFlo

[Next page](<https://devfeed.tech/tags/viewmodel.md?cursor=WyIyMDIxLTA5LTAyVDIzOjM4OjQyKzAwOjAwIiwgImExODdiYTNjLTY2NWUtNDk0NS1iNjhlLWFmODMyZDZhYzJkZCJd>)