# LiveData

Published articles for LiveData.

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

## A Simple MVI Architecture Approach Using LiveData

DevFeed: [A Simple MVI Architecture Approach Using LiveData](<https://devfeed.tech/articles/simple-mvi-32343.md>)

Original publisher: [Read original article](<https://dustn.dev/page/presentations/2019-08-14-simple-mvi/>)

Author: dustin@dustn.dev (Dustin Summers)

Published: 2026-09-17T04:13:15.404035Z

Content type: opinion

Language: en

Sources: [Dustin Summers](<https://devfeed.tech/sources/dustin-summers.md>)

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

Tags: [architecture](<https://devfeed.tech/tags/architecture.md>), [architecture-pattern](<https://devfeed.tech/tags/architecture-pattern.md>), [error](<https://devfeed.tech/tags/error.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [loading](<https://devfeed.tech/tags/loading.md>), [mvi](<https://devfeed.tech/tags/mvi.md>)

### AI overview

A talk from Android Summit 2019 discusses a simple implementation of the MVI architecture pattern using LiveData and the Loading, Content, Error pattern.

### Source excerpt

This was a talk provided by myself and Dan Lowe at Android Summit, 2019. In this we discuss a simple approach to the MVI (Model, View, Intent) Architecture Pattern using LiveData and the common Loading, Content, Error Pattern. Link to Dan's blog post is here which is what our talk was based around.

## 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...

## Be careful when converting Flow to LiveData

DevFeed: [Be careful when converting Flow to LiveData](<https://devfeed.tech/articles/be-careful-when-converting-flow-to-livedata-37158.md>)

Original publisher: [Read original article](<https://arkadiuszchmura.com/posts/be-careful-when-converting-flow-to-livedata/>)

Published: 2022-12-31T00:00:00Z

Content type: tutorial

Language: en

Sources: [Arkadiusz Chmura](<https://devfeed.tech/sources/arkadiusz-chmura.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [ui](<https://devfeed.tech/topics/ui.md>), [data](<https://devfeed.tech/topics/data.md>), [clients](<https://devfeed.tech/topics/clients.md>)

Tags: [clients](<https://devfeed.tech/tags/clients.md>), [code](<https://devfeed.tech/tags/code.md>), [flow](<https://devfeed.tech/tags/flow.md>), [function](<https://devfeed.tech/tags/function.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial explains a caveat when converting Kotlin Flow to LiveData: the resulting LiveData emits upstream updates only while it has an active observer. Without an observer, it remains inactive and may not receive the latest value.

### Source excerpt

LiveData created this way will only emit data when it has active observers.

## Smarter Shared Kotlin Flows

DevFeed: [Smarter Shared Kotlin Flows](<https://devfeed.tech/articles/smarter-shared-kotlin-flows-25883.md>)

Original publisher: [Read original article](<https://bladecoder.medium.com/smarter-shared-kotlin-flows-d6b75fc66754?source=rss-54910f05af37------2>)

Author: Christophe Beyls

Published: 2022-06-06T16:44:02Z

Content type: tutorial

Language: en

Sources: [Stories by Christophe Beyls on Medium](<https://devfeed.tech/sources/stories-by-christophe-beyls-on-medium.md>)

Topics: [kotlin-flow](<https://devfeed.tech/topics/kotlin-flow.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.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>), [database](<https://devfeed.tech/tags/database.md>), [efficiency](<https://devfeed.tech/tags/efficiency.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>)

### AI overview

This second article in a Kotlin Flow on Android series explains how SharedFlow and StateFlow using SharingStarted.WhileSubscribed() can restart upstream work when a lifecycle becomes active again. It compares this behavior with lifecycle-aware LiveData and proposes designing a Flow operator that propagates lifecycle state upstream to avoid unnecessary network requests or database queries.

### Source excerpt

Make the lifecycle available to the upstream Flow to skip unnecessary work This is the second part of a series of articles about using Kotlin Flow on Android. In the first part, we described the main limitation of Kotlin Flow when used inside ViewModel classes: When a SharedFlow or StateFlow using the SharingStarted.WhileSubscribed() strategy is collected again after the user navigates back to an Activity or Fragment, its source upstream Flow will always restart from scratch, sometimes resulting in unnecessary work being performed when the previously cached data was still valid. val results: StateFlow<SearchResult> = queryFlow.mapLatest { query -> repository.search(query) }.stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5000L), initialValue = SearchResult.EMPTY ) In the above example, repository.search() will be executed again even if the latest value of queryFlow didn't change in the meantime. This means a potential unnecessary network request or database query. LiveData doesn't suffer from this issue because its observers don't need to unsubscribe when they become inactive: LiveData is lifecycle-aware and will postpone the delivery of new results until it becomes active, while also ensuring that the same result will never be delivered to the same observer twice (even when it becomes active again). For more details I invite you to read the full article. At the end of this first part, we concluded that there was no simple and correct way to avoid performing this unnecessary work when relying only on the standard shareIn() or stateIn() operators. In this second part, we are going to solve that efficiency problem by designing a new Flow operator that will allow SharedFlows to integrate better with the lifecycle. Synchronizing with the LifecycleLiveData The core reason why LiveData deals with lifecycles better than Flow is because the lifecycle state is automatically propagated upstream through all the LiveData instances so they can all pause

## SharedFlow and StateFlow

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

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

Published: 2022-02-21T00:00:00Z

Content type: tutorial

Language: en

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

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

Tags: [channel](<https://devfeed.tech/tags/channel.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [scope](<https://devfeed.tech/tags/scope.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [value](<https://devfeed.tech/tags/value.md>), [values](<https://devfeed.tech/tags/values.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

A tutorial explaining Kotlin's SharedFlow and StateFlow for broadcasting and observing values among multiple coroutines. It covers replayed values, cancellation, interfaces for collecting and emitting, and converting a Flow with shareIn.

### Source excerpt

Known as a replacement for Subject, LiveData, and many more. SharedFlow and StateFlow are powerful coroutines classes, every Kotlin developer should know.

## 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

## Kotlin's Flow in ViewModels: it's complicated

DevFeed: [Kotlin's Flow in ViewModels: it's complicated](<https://devfeed.tech/articles/kotlin-s-flow-in-viewmodels-it-s-complicated-25882.md>)

Original publisher: [Read original article](<https://bladecoder.medium.com/kotlins-flow-in-viewmodels-it-s-complicated-556b472e281a?source=rss-54910f05af37------2>)

Author: Christophe Beyls

Published: 2021-08-28T10:42:09Z

Content type: tutorial

Language: en

Sources: [Stories by Christophe Beyls on Medium](<https://devfeed.tech/sources/stories-by-christophe-beyls-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Programming](<https://devfeed.tech/topics/programming.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>), [architecture-components](<https://devfeed.tech/tags/architecture-components.md>), [background-work](<https://devfeed.tech/tags/background-work.md>), [caching](<https://devfeed.tech/tags/caching.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [flow](<https://devfeed.tech/tags/flow.md>), [google](<https://devfeed.tech/tags/google.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [net-conf](<https://devfeed.tech/tags/net-conf.md>), [state](<https://devfeed.tech/tags/state.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article explains the challenges of loading UI data in Android applications when screen lifecycles and configuration changes are involved. It outlines goals such as caching valid data, pausing background work when screens are inactive, and avoiding unnecessary interruptions during configuration changes, then discusses ViewModel and LiveData as tools for addressing them.

### Source excerpt

LiveData is still your friend Loading UI data in Android applications can be challenging. The lifecycles of the various screens need to be taken into account, as well as configuration changes leading to the destruction and recreation of Activities. The individual screens of an app constantly toggle between interactive and hidden as the user navigates further and back in an app, switches from one app to another, or the device screen gets locked or unlocked. Each component needs to play fair and only perform active work when given the ball. Configuration changes happen on various occasions: when changing the device orientation, switching the app to multi-window mode or resizing its window size, switching to dark or light mode, changing the default locale or font sizes, and more. Goals of efficiency To achieve efficient data loading in Activities and Fragments leading to the best user experience, the following should be considered: Caching: data that has been loaded successfully and is still valid should be delivered immediately and not loaded a second time. In particular, when an existing Activity or Fragment becomes visible again, or after an Activity gets recreated on configuration change; Avoiding background work: when an Activity or Fragment becomes invisible (moves from the STARTED to the STOPPED state), any ongoing loading work should be paused or canceled in order to save resources. This is especially important for endless streams of data like location updates or periodic refreshes of any kind; No work interruption during configuration changes: this is an exception to the second goal. During configuration changes, an Activity gets replaced by a new instance of it while preserving its state, so canceling ongoing work when the old instance is destroyed to immediately restart it when the new instance is created would be counter-productive. Today: ViewModel and LiveData To help developers reach these goals with code of manageable complexity, Google released the fir

## Fun with Compose: Bad UI in a Great Framework - Touchlab

DevFeed: [Fun with Compose: Bad UI in a Great Framework - Touchlab](<https://devfeed.tech/articles/fun-with-compose-bad-ui-in-a-great-framework-touchlab-38204.md>)

Original publisher: [Read original article](<https://touchlab.co/fun-with-compose-bad-ui-in-a-great-framework>)

Published: 2021-08-04T03:23:44Z

Content type: article

Language: en

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

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Boilerplate](<https://devfeed.tech/topics/boilerplate.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [animations](<https://devfeed.tech/tags/animations.md>), [boilerplate](<https://devfeed.tech/tags/boilerplate.md>), [compose](<https://devfeed.tech/tags/compose.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [recomposition](<https://devfeed.tech/tags/recomposition.md>), [state](<https://devfeed.tech/tags/state.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

An exploration of Jetpack Compose that builds deliberately poor volume-control interfaces and reflects on the framework's development experience. The article highlights concise UI code, custom animations, reduced boilerplate, and lessons about state, mutation, and recomposition.

### Source excerpt

To celebrate Jetpack Compose finally hitting 1.0, I decided to bring back an old reddit trend of creating the absolute worst volume control UI possible.

## Converting LiveData to Flow: More lessons learned

DevFeed: [Converting LiveData to Flow: More lessons learned](<https://devfeed.tech/articles/converting-livedata-to-flow-more-lessons-learned-25903.md>)

Original publisher: [Read original article](<https://chao2zhang.medium.com/converting-livedata-to-flow-more-lessons-learned-ba1e068115f5?source=rss-d19045640fe------2>)

Author: Chao Zhang

Published: 2021-06-23T06:52:18Z

Content type: tutorial

Language: en

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

Topics: [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [test](<https://devfeed.tech/topics/test.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>), [cancellation](<https://devfeed.tech/tags/cancellation.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>)

### AI overview

This continuation explains lessons from converting between Kotlin Flow and LiveData in Android. It covers unfinished hot-flow coroutines during unit tests, why asLiveData cancellation occurs after a timeout on Dispatchers.Main, and how values are replayed when LiveData becomes active again.

### Source excerpt

Photo: Buzz Andersen from Unsplash Android KTX provides opinionated methods facilitating using Kotlin Coroutines in Android Architecture Components. For instance, Flow<T>.asLiveData() is quite helpful to migrate your apps using LiveData towards coroutine. Make sure to understand their behaviors underneath before using them! This story is a continuation of the previous one. Lesson III: Unfinished coroutines during unit testshttps://medium.com/media/41979239402051494c1002bb4d9e57dc/href When converting from Flow to LiveData, the source stream might be a hot StateFlow like above. Running the test will actually end up with the following error: kotlinx.coroutines.test.UncompletedCoroutinesError: Unfinished coroutines during teardown. Ensure all coroutines are completed or cancelled by your test. We know a hot Flow like SharedFlow never completes, so this error appears reasonable. A common way to test hot flow is to cancel the coroutine that the hot flow is executed on. In this case, we may want to pass a custom coroutineContext to asLiveData(context = ...)and cancel the job when the assertions are done: https://medium.com/media/129968c37bf50ac019a25755e3c56411/href However, it does not work! Let's take a step back and consult the documentation of Flow<T>.asLiveData : If the LiveData becomes inactive (LiveData.onInactive) while the flow has not completed, the flow collection will be cancelled after timeoutInMs milliseconds unless the LiveData becomes active again before that timeout (to gracefully handle cases like Activity rotation). Since we are converting a hot flow to LiveData, we will always meet the condition. The flow collection will be canceled after timeoutInMs (default is 5 seconds). After digging it a bit more into the source code, we find that the cancellation is implemented as a delay() call on Dispatchers.Main : https://medium.com/media/154954407331c372f002028c8353a843/href The reason why cancel()runs on Dispatchers.Main is because it is invoked byLiveData.onI

## Debugging LiveData changes made easy

DevFeed: [Debugging LiveData changes made easy](<https://devfeed.tech/articles/debugging-livedata-changes-made-easy-25904.md>)

Original publisher: [Read original article](<https://chao2zhang.medium.com/debugging-livedata-changes-made-easy-d3aa16b81b41?source=rss-d19045640fe------2>)

Author: Chao Zhang

Published: 2021-04-08T21:16:44Z

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>), [debugging](<https://devfeed.tech/topics/debugging.md>), [Logging](<https://devfeed.tech/topics/logging.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-architecture](<https://devfeed.tech/tags/android-architecture.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [architecture-components](<https://devfeed.tech/tags/architecture-components.md>), [bytecode](<https://devfeed.tech/tags/bytecode.md>), [class](<https://devfeed.tech/tags/class.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [java](<https://devfeed.tech/tags/java.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [logging](<https://devfeed.tech/tags/logging.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>)

### AI overview

This tutorial examines the difficulties of debugging LiveData changes in larger Android applications. It compares breakpoints and logging, explains why both become less effective as observing chains grow, and identifies minimal code changes and historical state information as key requirements for a better approach.

### Source excerpt

Photo by Markus Spiske from Unsplash Have you ever got frustrated to debug LiveData changes by adding numerous log statements or breakpoints? As the core data structure of Android Architecture Components, LiveData is used widely in many apps to hold observable data. However, its debugging experience could still be a pain point after these many years. Observing LiveData changes at scale There are two traditional yet powerful methods for observing LiveData changes: Debugging and logging. When it comes to debugging, we mostly interact with our IDE and do not need to touch any code. We can simply click "Debug" or "Attach Debugger to Android Process" in Android Studio and expect the process to be paused at the preset debug breakpoints. Debugging in observers In terms of logging, we can add logging statements to our observers to know when they are called. When we rerun the app, we should be able to view those log statements through Logcat while interacting with the app. https://medium.com/media/bd34828e0230fe59c141c0e820c7436e/href Both debugging and logging are effective when we have simple LiveData observing chains. While we are iterating our app with new features and business logics, we may find it necessary to scale up our app into the recommended app architecture illustrated below. As you can tell, LiveData becomes more universally used as the data holder type across different components. In other words, LiveData observing chains merely get longer and more complex. App Architecture using LiveData When debugging our app at scale, logging might be less effective, because we do not want to change code at multiple places to debug. Alternatively, we could also build an abstract class LoggingObserver<T> : Observer<T>that adds log statements in onChanged(data: T) , and require all observers to inherit from LoggingObserver. This plausible approach is cumbersome since it requires large-scale refactoring of our app code. Using debugging may not be effective either: We need to

## Converting LiveData to Flow: Lessons learned

DevFeed: [Converting LiveData to Flow: Lessons learned](<https://devfeed.tech/articles/converting-livedata-to-flow-lessons-learned-25902.md>)

Original publisher: [Read original article](<https://chao2zhang.medium.com/converting-livedata-to-flow-lessons-learned-9362a00611c8?source=rss-d19045640fe------2>)

Author: Chao Zhang

Published: 2021-04-03T01:13:26Z

Content type: tutorial

Language: en

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

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [network](<https://devfeed.tech/tags/network.md>), [retrofit](<https://devfeed.tech/tags/retrofit.md>), [rotation](<https://devfeed.tech/tags/rotation.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial examines lessons from converting Kotlin Flow to LiveData with Flow<T>.asLiveData() in an Android app. It explains why flow collection may be re-executed after screen rotation and identifies creating a new LiveData instance instead of preserving it as a property as the bug causing recollection.

### Source excerpt

Photo: Robert Lukeman from Unsplash Android KTX provides opinionated methods, such asFlow<T>.asLiveData(), facilitating using Kotlin Coroutines in Android Architecture Components. Make sure to understand their behaviors underneath before using them! The official documentation on Kotlin coroutines on Android is quitewell-written, while there are numerous article posts covering the basics. In this story, we will focus on the lessons learned when using these extension methods, usingFlow<T>.asLiveData() as an example. Setup Let's start with a concrete example using the orthodox Android App Architecture: Repository + ViewModel + Fragment https://medium.com/media/a59f3702376fe64d61dd5c3dd72c9c15/href RedditService is a simple Retrofit service. We also added logging statements inside the flow collecting block. https://medium.com/media/a904400508a241bae454d44e0f01a9b9/href We use Flow<T>.asLiveData() to convert the flow into a LiveData. https://medium.com/media/97cb5995c53c5d86606a371ef905d25d/href In the fragment layer, we added logging statements for the fragment lifecycle calls and used Thread.sleep(500)to simulate complex layout inflation. Lesson I: Flow collection is re-executed after rotating the screen When we run the app, it looks fine. However, after rotating the device screen to recreate the fragment, we can observe more logs like flow running... indicating the flow is executed. 2021-04-02 16:41:32.246 I: Fragment onCreate... 2021-04-02 16:41:32.247 I: Fragment onCreateView... 2021-04-02 16:41:32.754 I: Fragment onStart... 2021-04-02 16:41:32.755 I: flow running... 2021-04-02 16:41:32.756 I: Fragment onResume... 2021-04-02 16:41:33.309 I: Observer called... That is weird! The original intention of ViewModel is to persist data that can survive UI recreation. After we rotate the device screen, the data should be retrieved from the storage. Contrarily, what we saw is that the data is fetched again from the service, which may cause unnecessary network calls or UI flic

## Modelling UI State on Android

DevFeed: [Modelling UI State on Android](<https://devfeed.tech/articles/modelling-ui-state-on-android-25873.md>)

Original publisher: [Read original article](<http://lordraydenmk.github.io//2021/modelling-ui-state/>)

Author: Stojan Anastasov

Published: 2021-01-29T00:00:00Z

Content type: tutorial

Language: en

Sources: [Stojan Anastasov's blog](<https://devfeed.tech/sources/stojan-anastasov-s-blog.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [cardinality](<https://devfeed.tech/tags/cardinality.md>), [data-class](<https://devfeed.tech/tags/data-class.md>), [data-structure](<https://devfeed.tech/tags/data-structure.md>), [fp](<https://devfeed.tech/tags/fp.md>), [functional](<https://devfeed.tech/tags/functional.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [sealed-class](<https://devfeed.tech/tags/sealed-class.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [types](<https://devfeed.tech/tags/types.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article explains how to model Android UI state in Kotlin using data classes and sealed classes. It connects types with sets and cardinality, then describes product types and sum types as tools for representing valid application states.

### Source excerpt

The recommended approach from Google for Android development is holding the UI state in a ViewModel and having the View observe it. To achieve that one can use LiveData, StateFlow, RxJava or a similar tool. But how to model the UI state? Use a data class or a sealed class? Use one observable property or many? I will describe the tradeoffs between the approaches and present a tool to help you decide which one to use. This article is heavily inspired by Types as Sets from the Elm guide, a large part is a translation from Elm to Kotlin. Photo by Marc-Olivier Jodoin on Unsplash Types as sets By Making Data Structure we can make sure the possible values in code exactly match the valid values in real life. Doing that helps to avoid a whole class of bugs related to invalid data. To achieve that, first we need to understand the relationship between Types and Sets. We can think of Types as sets of values, they contain unique elements and there is no ordering between them. For example: Nothing - the empty set, it contains no elements Unit - the singleton set, it contains one element - Unit Boolean - contains the elements true and false Int - contains the elements: ... -2, -1, 0, 1, 2 ... Float - contains the elements: 0.1, 0.01, 1.0 .... String - contains the elements: "", "a", "b", "Kotlin", "Android", "Hello world!"... So when you write: val x: Boolean it means x belongs to the set of Boolean values and can be either true or false. Cardinality In Mathematics, Cardinality is the measure of "number of elements" of a Set. For example the set of Boolean contains the elements [true, false] so it has a cardinality = 2. Let's take a look at the cardinality of the sets mentioned above: Nothing - 0 Unit - 1 Boolean - 2 Short - 65535 Int - ∞ Float - ∞ String- ∞ Note: The cardinality of Int and Float is not exactly infinity, it's 2^32 however that is a huge number. When building apps, we use built-in types and create custom types using constructs like data classes and sealed classes. Product

## Avoid backing properties for LiveData and StateFlow

DevFeed: [Avoid backing properties for LiveData and StateFlow](<https://devfeed.tech/articles/avoid-backing-properties-for-livedata-and-stateflow-25886.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/avoid-backing-properties-for-livedata-and-stateflow-706006c9867e?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2021-01-12T14:03:52Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [coding](<https://devfeed.tech/topics/coding.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [abstract-class](<https://devfeed.tech/tags/abstract-class.md>), [android](<https://devfeed.tech/tags/android.md>), [class](<https://devfeed.tech/tags/class.md>), [clean-code](<https://devfeed.tech/tags/clean-code.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interface](<https://devfeed.tech/tags/interface.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [val](<https://devfeed.tech/tags/val.md>), [var](<https://devfeed.tech/tags/var.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This Kotlin article argues that developers can avoid duplicated backing properties when exposing LiveData and StateFlow. It proposes separating the public API from the implementation with interfaces or an abstract class, including in ViewModels.

### Source excerpt

https://unsplash.com/photos/OopPIi_A428 If you have ever worked with LiveData you probably have written code similar to this: class MyViewModel: ViewModel() { val loading: LiveData<Boolean> get() = _loading private val _loading = MutableLiveData<Boolean>()} This seems nowadays the typical way developers would expose some immutable LiveData, while being able to have a mutable version inside the implementation we would write data into. Every time I saw, or even had to write, this kind of code something cringed inside me. As I quoted in one of my talks this feeling in our brain is for real: social missteps activate regions in the brain, [..] that have been previously associated with physical pain. As developers, we know something is wrong with this code, right? It also feels like we are writing manual getters and setters here. What's wrong? We could start with the prefix we use for the backing field, although we fought hard for a long time to get rid of prefixes, we accept it here! It is even made it into the official coding conventions. But even if we rename it, it still cringes: class MyViewModel: ViewModel() { val loading: LiveData<Boolean> get() = mutableLoading private val mutableLoading = MutableLiveData<Boolean>()} This duplication feels unneeded! Especially if you write something like a ViewModel that exposed many of these, you get lost in reading the code just by all these duplications. But it's just LiveData? You might think it's just a specialty of LiveData and the future of that construct might be a more limited one. And you would not have this issue with primitives. The language supports this out of the box with a private setter: var secret: String = "Secret" private set But there is a new kid in town: StateFlow needs the same thing! Look at this snippet from the official Jetbrains blog: class DownloadingModel { private val _state = MutableStateFlow<DownloadStatus>(DownloadStatus.NOT_REQUESTED) val state: StateFlow<DownloadStatus> get() = _state This probl

## When LiveData and Kotlin don't play well together

DevFeed: [When LiveData and Kotlin don't play well together](<https://devfeed.tech/articles/when-livedata-and-kotlin-don-t-play-well-together-25889.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/when-livedata-and-kotlin-dont-play-hand-in-hand-30149aa794ec?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2020-12-15T13:38:10Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [bug](<https://devfeed.tech/topics/bug.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Code](<https://devfeed.tech/topics/code.md>), [implementation](<https://devfeed.tech/topics/implementation.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>), [bug](<https://devfeed.tech/tags/bug.md>), [code](<https://devfeed.tech/tags/code.md>), [explore](<https://devfeed.tech/tags/explore.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [rotation](<https://devfeed.tech/tags/rotation.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how LiveData's sticky last-value behavior interacts with Kotlin nullability on Android. It examines attempts to consume values by resetting LiveData to null and explains how that can cause a runtime crash when the value is treated as non-nullable.

### Source excerpt

When LiveData and Kotlin don't play well togetherPlaying well together The idea of LiveData was an interesting one. Based on the idea of reactive streams, that was on the peak at that time with RxJava plus adding automatic lifecycle handling -- a problem on Android. LiveData had bad timing though. It arrived just before Kotlin made its impact in the Android community and sometimes both don't play that nice together. Let's explore why and what can happen! The good and the bad The idea of LiveData was pretty simple: a lifecycle-aware implementation of the Observable pattern. In addition, if you resubscribe, you will get the last emitted value again. It could be compared to a typed version of an EventBus with sticky messages. This is one of the core features of LiveData. But very soon after developers, including the authors, figured, you don't always want that behavior. Let's say you have an error value. Then you probably don't want to show that error value again after resubscribing, like after rotation of a device -- for instance. One way to solve this is SingleLiveEvent and it's a good choice for one-off events like errors. Both worlds But what if you want a bit of both? You want to have the last value "sticky" plus not showing potential errors multiple times! In that case, it would be good to remove our error value from LiveData after they have been consumed, right? Let's look at the implementation ofLiveData: The current value is saved on a field: private volatile Object mData; Initially, it is set to NOT_SET which. static final Object NOT_SET = new Object(); Unfortunately, is not public otherwise, we could use it to reset the value. What now? If you search for this problem, one of the most suggested solutions is simply setting it to null. Let's explore this: viewModel.results.observe(lifecycleOwner) { result -> when (result) { SomeResult.Error -> { handleError() viewModel.results.reset() } SomeResult.Result -> { handleResult(result) } } } where the ViewModel's imple

## Building Reactive UIs with LiveData and SavedStateHandle (or equivalent approaches)

DevFeed: [Building Reactive UIs with LiveData and SavedStateHandle (or equivalent approaches)](<https://devfeed.tech/articles/building-reactive-uis-with-livedata-and-savedstatehandle-or-equivalent-approaches-25928.md>)

Original publisher: [Read original article](<https://itnext.io/building-reactive-uis-with-livedata-and-savedstatehandle-or-equivalent-approaches-4e934487035f?source=rss-7a8d96da8cb6------2>)

Author: Gabor Varadi

Published: 2020-10-04T19:53:05Z

Content type: tutorial

Language: en

Sources: [Stories by Gabor Varadi on Medium](<https://devfeed.tech/sources/stories-by-gabor-varadi-on-medium.md>)

Topics: [reactive](<https://devfeed.tech/topics/reactive.md>), [Android](<https://devfeed.tech/topics/android.md>), [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [observable](<https://devfeed.tech/tags/observable.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [reactive-programming](<https://devfeed.tech/tags/reactive-programming.md>), [room](<https://devfeed.tech/tags/room.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [savedstatehandle](<https://devfeed.tech/tags/savedstatehandle.md>)

### AI overview

This article explains LiveData as a reactive, observable, lifecycle-aware data holder for Android applications. It argues that LiveData remains useful alongside RxJava and Kotlin coroutines because its lifecycle activation states allow it to represent reactive data sources, including Room-backed data that refreshes after invalidation.

### Source excerpt

Building Reactive UIs with LiveData and SavedStateHandle (or equivalent approaches like Rx) You can also follow the related discussion thread on /r/android_devs. LiveData is a misunderstood beast. Every so often, you see comments like "LiveData does not belong in Repositories", or that with the existence of RxJava, Coroutine Channels, or Coroutine Flows -- there's "no reason to use LiveData at all". While there are components in these libraries that have overlapping responsibilities (BehaviorRelay, ConflatedBroadcastChannel, MutableStateFlow), that doesn't mean LiveData is useless. With the relatively new additions to Jetpack, such as the liveData { coroutine builder, LiveData is actually quite interesting. What is LiveData? If you try to find a definition for LiveData, you'll find that it's a "reactive, observable, lifecycle-aware data holder". We know it can be observed, and we know it holds 1 data value that is re-emitted for any new observer (and any changes made to it are also emitted), just like any BehaviorRelay. But what makes it special? Due to LiveData's lifecycle-awareness, it comes with its own "activation state" ( onActive and onInactive). It lets you know when there is an active observer, and when there are no longer any active observers. The trick is that this makes it far more than "just an every-day data holder". This allows LiveData to represent reactive datasources. I'd even wager that this is the original purpose for which LiveData was created, if Room's ComputableLiveData is any indication (as that also relies on onActive to trigger the refresh of the query results, if the table had been invalidated by a write to it). Why do I want reactive datasources? If you have data or state that can change over time, it's significantly easier to be notified of changes, than it is to poll for possible changes (and potentially miss out on changes if we tried to fetch data at the wrong time). This means that by using an "observer" (or change listener), we can r

## Communicating with your Lifecycle Owner using RxJava

DevFeed: [Communicating with your Lifecycle Owner using RxJava](<https://devfeed.tech/articles/communicating-with-your-lifecycle-owner-using-rxjava-25872.md>)

Original publisher: [Read original article](<http://lordraydenmk.github.io//2020/viewmodel-lifecycle-owner-communication-rx/>)

Author: Stojan Anastasov

Published: 2020-09-08T00:00:00Z

Content type: tutorial

Language: en

Sources: [Stojan Anastasov's blog](<https://devfeed.tech/sources/stojan-anastasov-s-blog.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-architecture](<https://devfeed.tech/tags/android-architecture.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [development](<https://devfeed.tech/tags/development.md>), [google](<https://devfeed.tech/tags/google.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [libraries](<https://devfeed.tech/tags/libraries.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [subscription](<https://devfeed.tech/tags/subscription.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains LiveData in Android Jetpack, including lifecycle-aware observation, event handling, and use in the data layer. It compares LiveData with RxJava and Kotlin Flow, then describes a reactive RxJava approach for state observation and lifecycle-managed subscriptions.

### Source excerpt

Google introduced Jetpack, a family of opinionated libraries to make Android development easier a few years ago. One of the core classes in Jetpack is LiveData - an observable, lifecycle aware data holder. The typical use case is having a ViewModel that exposes LiveData as a property, and observing it from your lifecycle owner, a Fragment or an Activity. A typical usage would look like this: data class MyState(val value: String) class MyViewModel : ViewModel { private val _state = MutableLiveData<MyState>() val state: LiveData<MyState> get() = _state } class MyFragment : Fragment { val viewModel by viewModels<MyViewModel>() override fun onViewCreated() { viewModel.state.observe(this, Observer(::handleState)) } private fun handleState(state: MySate): Unit = TODO() } There are multiple benefits of using LiveData: Your observer is notified when the data changes The observer is only notified of changes when it's active Observers are notified when they become active again, like entering into foreground etc Check the LiveData docs for all benefits. LiveData and Events In situations like showing a Snackbar/dialog or navigating to a different Activity/Fragment the ViewModel also needs to notify the LifecycleOwner. A plain old LiveData doesn't work well here because it caches the last item. As a workaround, in the official Android architecture samples there is a SingleLiveEvent implementation of LiveData. Data Layer But what about the rest of the app? You can use LiveData in your data layer, in fact Room, the persistence library from Jetpack, support LiveData as the return type natively. However while using LiveData across all the layer in the app is possible, it is less than ideal. The operations are always executed on the Main Thread and it comes with limited number of transformation functions compared to RxJava or Flow. To fix this problem LiveData comes with adapters for both RxJava and Flow from KotlinX Coroutines. This means developers can use RxJava or Flow in their d

## Refactoring from LiveData to Coroutines & Flow

DevFeed: [Refactoring from LiveData to Coroutines & Flow](<https://devfeed.tech/articles/refactoring-from-livedata-to-coroutines-flow-25969.md>)

Original publisher: [Read original article](<https://jossiwolf.medium.com/refactoring-from-livedata-to-coroutines-flow-e73b6c59f5ad?source=rss-8efc0359e234------2>)

Author: Jossi Wolf

Published: 2020-08-24T16:29:47Z

Content type: tutorial

Language: en

Sources: [Stories by Jossi Wolf on Medium](<https://devfeed.tech/sources/stories-by-jossi-wolf-on-medium.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [coroutines-flow](<https://devfeed.tech/tags/coroutines-flow.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [migration](<https://devfeed.tech/tags/migration.md>), [network](<https://devfeed.tech/tags/network.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [threading](<https://devfeed.tech/tags/threading.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial describes migrating Android repositories from LiveData to Kotlin Coroutines and Flow. It distinguishes one-shot operations from data streams and introduces migration helpers to preserve compatibility during a gradual refactor.

### Source excerpt

If you haven't, I recommend reading my other post about LiveData in Repositories. We recently joined a new project with heavy LiveData usage, everywhere. The search for main thread blockages led us down a rabbit hole of removing a significant portion of our LiveData usages. Here's how we migrated our Repositories from LiveData. We were faced with a tough challenge: We had to migrate as quickly and smoothly as possible -- there was no time for huge interruptions. Having all our repositories and lots of helper classes use LiveData, this left us with two options: Make sure we get threading right in all places that use LiveData Replace LiveData in our Repositories Making sure we're on the right thread everywhere and continuing to use LiveData would be the solution requiring fewer changes, but we would still be using LiveData for a use case it isn't really designed for. It can not be said often enough: LiveData has nothing to do in layers not related to UI! Keep it out of Repositories, DataSources! There use Flow or RxJava and only put LiveData in your ViewModels!It was very unfortunate that this was shown by Google as best practice. 😪 https://t.co/zOnbmyJYDP Agreed, 💯! We're actually working on revamping this guide which hasn't been updated with the latest recommendations for a looong time 🙈 Our code was also quite convoluted and hard to fix, so we decided to look for another option to handle asynchronicity. In an ideal world, refactoring it would have been easier, and we probably would have stuck with LiveData had our code been less convoluted. Our main requirement was for our replacement to fit with our existing mental model -- ViewModels being able to observe data from repositories where needed. Looking at our code, we were able to categorise our LiveData use cases into two categories: One-shot LiveData, for example, network calls Streams of data (e.g. for retrieving cached data before emitting fresh data) Our Replacement We looked around for a bit and decided to go wi

## Fragment Lifecycles in the Age of Jetpack

DevFeed: [Fragment Lifecycles in the Age of Jetpack](<https://devfeed.tech/articles/fragment-lifecycles-in-the-age-of-jetpack-27062.md>)

Original publisher: [Read original article](<https://zsmb.co/fragment-lifecycles-in-the-age-of-jetpack/>)

Author: Márton Braun

Published: 2020-06-18T16:00:00Z

Content type: tutorial

Language: en

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

Topics: [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [App](<https://devfeed.tech/topics/app.md>), [Dark Mode](<https://devfeed.tech/topics/dark-mode.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [code](<https://devfeed.tech/tags/code.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dark-mode](<https://devfeed.tech/tags/dark-mode.md>), [fragment](<https://devfeed.tech/tags/fragment.md>), [fragments](<https://devfeed.tech/tags/fragments.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [marton-braun](<https://devfeed.tech/tags/marton-braun.md>), [scope](<https://devfeed.tech/tags/scope.md>), [ui](<https://devfeed.tech/tags/ui.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 Android Fragment lifecycles in the Jetpack ecosystem, covering the Fragment instance lifecycle and the nested view lifecycle. It describes recreation during state restoration, configuration changes, and process death, along with lifecycle methods, state handling, and resource management.

### Source excerpt

Fragments have... Complicated lifecycles, to say the least. Let's take a look at these, and how they all fit into the world of Jetpack today, with LifecycleOwners, LiveData, and coroutines.

## Handling Transient Events

DevFeed: [Handling Transient Events](<https://devfeed.tech/articles/handling-transient-events-30594.md>)

Original publisher: [Read original article](<https://ryanharter.com/blog/2019/07/handling-transient-events/>)

Published: 2019-07-26T15:00:00Z

Content type: tutorial

Language: en

Sources: [Blogs on Ryan Harter](<https://devfeed.tech/sources/blogs-on-ryan-harter.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [events](<https://devfeed.tech/tags/events.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [notifications](<https://devfeed.tech/tags/notifications.md>), [view](<https://devfeed.tech/tags/view.md>)

### AI overview

This article explains why LiveData is well suited to persistent view state but less suited to transient view events. It distinguishes state that should be saved and restored from one-time events such as notifications, navigation, dialogs, and errors, using an Android app example.

### Source excerpt

LiveData has become an important part of many Android apps. With it's elegant handling of the complex lifecycle inherent in many Android components, its understandable that we would try to use them everywhere we can. LiveData, however, was designed with a very specific use case in mind. Its intended to hold data for use by views in an application, and make that data available in a lifecycle-safe fashion, while helping us reduce the need to reload data unnecessarily.

## Encapsulating View State

DevFeed: [Encapsulating View State](<https://devfeed.tech/articles/encapsulating-view-state-30593.md>)

Original publisher: [Read original article](<https://ryanharter.com/blog/2019/07/encapsulating-view-state/>)

Published: 2019-07-19T16:00:00Z

Content type: tutorial

Language: en

Sources: [Blogs on Ryan Harter](<https://devfeed.tech/sources/blogs-on-ryan-harter.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [app](<https://devfeed.tech/tags/app.md>), [app-architecture](<https://devfeed.tech/tags/app-architecture.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [code](<https://devfeed.tech/tags/code.md>), [error](<https://devfeed.tech/tags/error.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [messages](<https://devfeed.tech/tags/messages.md>), [testing](<https://devfeed.tech/tags/testing.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article presents an approach to encapsulating view state in Android applications with AndroidX ViewModel. It explains how putting business logic and decision-making code in ViewModels can simplify Activities and Fragments and make the valuable code easier to test.

### Source excerpt

The AndroidX ViewModel has become a central component in many modern Android apps. They offer a relatively simple abstraction to encapsulate business logic and decision making code which separates it from the platform frameworks, which are often difficult to test. Since ViewModels are easier to test than Framework classes like Activity and Fragment due to their simple lifecycles and lack of external dependencies, it makes sense to try to put as much logic, the complex decision-making code that should be tested, in ViewModels as possible. Ideally we'll be left with a view layer, either Activities, Fragments, or something else, which is so simple that it's not worth testing.

## Data Binding on Android to implement the real MVVM

DevFeed: [Data Binding on Android to implement the real MVVM](<https://devfeed.tech/articles/data-binding-on-android-to-implement-the-real-mvvm-27154.md>)

Original publisher: [Read original article](<https://antonioleiva.com/data-binding-on-android-to-implement-the-real-mvvm>)

Published: 2019-05-15T00:00:00Z

Content type: tutorial

Language: en

Sources: [Antonio Leiva](<https://devfeed.tech/sources/antonio-leiva.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [code](<https://devfeed.tech/tags/code.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [ui](<https://devfeed.tech/tags/ui.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

This tutorial explains how Android Data Binding connects data to UI elements, reduces boilerplate such as findViewById, and can be applied to the MVVM presentation pattern. It also describes integration with LiveData for responding to model changes and matching XML views with binding-object properties.

### Source excerpt

Everything Android, Kotlin and other random topics

## Testing LiveData in JUnit 4 and JUnit 5

DevFeed: [Testing LiveData in JUnit 4 and JUnit 5](<https://devfeed.tech/articles/testing-livedata-in-junit-4-and-junit-5-28675.md>)

Original publisher: [Read original article](<https://jeroenmols.com/blog/2019/01/17/livedatajunit5/>)

Author: info@jeroenmols.com (Jeroen Mols)

Published: 2019-01-17T00:00:00Z

Content type: tutorial

Language: en

Sources: [Jeroen Mols](<https://devfeed.tech/sources/jeroen-mols.md>)

Topics: [Testing](<https://devfeed.tech/topics/testing.md>), [Android](<https://devfeed.tech/topics/android.md>), [test](<https://devfeed.tech/topics/test.md>), [unit tests](<https://devfeed.tech/topics/unit-tests.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [architecture-components](<https://devfeed.tech/tags/architecture-components.md>), [blogs](<https://devfeed.tech/tags/blogs.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [junit](<https://devfeed.tech/tags/junit.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [testing](<https://devfeed.tech/tags/testing.md>), [unit-test](<https://devfeed.tech/tags/unit-test.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A tutorial on testing Android LiveData with JUnit 4 and JUnit 5. It explains why JVM unit tests cannot use Android's main thread directly and shows how JUnit rules or JUnit 5 extensions can update LiveData synchronously on the calling thread.

### Source excerpt

Architecture components are one of the most exciting things that happened to Android in the past years. But how do you effectively go about and testing this?

## Using Kotlin to Simplify Android Architecture Components

DevFeed: [Using Kotlin to Simplify Android Architecture Components](<https://devfeed.tech/articles/hacking-architecture-components-by-using-kotlin-27135.md>)

Original publisher: [Read original article](<https://antonioleiva.com/architecture-components-kotlin>)

Published: 2018-03-13T00:00:00Z

Content type: tutorial

Language: en

Sources: [Antonio Leiva](<https://devfeed.tech/sources/antonio-leiva.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [architecture-components](<https://devfeed.tech/tags/architecture-components.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial introduces Android Architecture Components, focusing on ViewModel and LiveData, and shows how Kotlin can make their use simpler. It also discusses lifecycle handling, configuration changes, and testing.

### Source excerpt

Everything Android, Kotlin and other random topics

## Avoiding LiveData observer leaks in the Android Fragment lifecycle

DevFeed: [Avoiding LiveData observer leaks in the Android Fragment lifecycle](<https://devfeed.tech/articles/architecture-components-pitfalls-part-1-25878.md>)

Original publisher: [Read original article](<https://bladecoder.medium.com/architecture-components-pitfalls-part-1-9300dd969808?source=rss-54910f05af37------2>)

Author: Christophe Beyls

Published: 2017-10-24T19:31:14Z

Content type: tutorial

Language: en

Sources: [Stories by Christophe Beyls on Medium](<https://devfeed.tech/sources/stories-by-christophe-beyls-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [configuration](<https://devfeed.tech/topics/configuration.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>), [architecture](<https://devfeed.tech/tags/architecture.md>), [architecture-components](<https://devfeed.tech/tags/architecture-components.md>), [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [deprecated](<https://devfeed.tech/tags/deprecated.md>), [fragments](<https://devfeed.tech/tags/fragments.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [memory](<https://devfeed.tech/tags/memory.md>), [memory-leak](<https://devfeed.tech/tags/memory-leak.md>), [performance](<https://devfeed.tech/tags/performance.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article explains a pitfall when subscribing to LiveData from an Android Fragment. Detaching and re-attaching a Fragment can create a new observer while the previous observer remains active, causing duplicate execution, a memory leak, and a performance problem until the Fragment is destroyed.

### Source excerpt

LiveData and the Fragment lifecycle The new Android Architecure Components are soon to be announced as stable after a few months of public testing. A lot has already been written about the basics (starting with the very good documentation) so I won't cover them here. Instead I would like to focus on important pitfalls that are mostly undocumented and rarely discussed and may cause issues in your applications if you miss them. In this first article, I'll talk about our beloved Fragments. Edit (14 may 2018): Google has finally fixed the issue in support library 28.0.0 and AndroidX 1.0.0. See solution 4 below.Edit (13 march 2020): onActivityCreated() has been officially deprecated and onViewCreated() should be used instead. The code samples in this article have been updated accordingly. The Architecture Components provide default ViewModelProvider implementations for activities and fragments. They allow you to store LiveData instances inside a ViewModel to be reused across configuration changes. The usage with activities is quite straightforward because the activity lifecyle maps well to the Lifecycle interface of the Architecture Components, but the fragment lifecycle is more complex and may cause subtle side effects if you're not being careful. The Fragment lifecycle (simplified version) Fragments can be detached and re-attached. When they are detached, their view hierarchy is destroyed and they become invisible and inactive, but their instance is not destroyed. When they are later re-attached, a new view hierarchy is created and onCreateView() and onViewCreated() are called again. For this reason, the usually recommended place to initialize Loaders and other asynchronous loading operations that will eventually interact with the view hierarchy is in onViewCreated(). We can assume this is also the best place to initialize LiveData instances by subscribing a new Observer. Most of the official Architecture Components samples also do it there. You would expect typical co

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