# main thread

Published articles for main thread.

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

## @MainActor in Swift explained with code examples

DevFeed: [@MainActor in Swift explained with code examples](<https://devfeed.tech/articles/mainactor-in-swift-explained-with-code-examples-11486.md>)

Original publisher: [Read original article](<https://www.avanderlee.com/swift/mainactor-dispatch-main-thread/>)

Author: Antoine van der Lee

Published: 2026-08-02T12:04:47Z

Content type: tutorial

Language: en

Sources: [SwiftLee](<https://devfeed.tech/sources/swiftlee.md>)

Topics: [Swift](<https://devfeed.tech/topics/swift.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Code](<https://devfeed.tech/topics/code.md>), [Xcode](<https://devfeed.tech/topics/xcode.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [dispatchqueue](<https://devfeed.tech/tags/dispatchqueue.md>), [examples](<https://devfeed.tech/tags/examples.md>), [guide](<https://devfeed.tech/tags/guide.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [swift](<https://devfeed.tech/tags/swift.md>), [thread](<https://devfeed.tech/tags/thread.md>), [xcode](<https://devfeed.tech/tags/xcode.md>)

### AI overview

This tutorial explains how Swift's @MainActor global actor ensures that properties, methods, instances, and closures execute on the main thread. It also covers compiler-enforced main-thread execution, global actor isolation, nonisolated methods, and changes to default actor isolation in Swift 6.2 and Xcode 26.

### Source excerpt

@MainActor is a global actor that performs its tasks on the main thread. You can use it to dispatch to the main thread by marking properties, methods, instances, or closures with the attribute. Instead of manually dispatching using DispatchQueue.main.async, you let the compiler enforce main thread execution for you. If you're new to Actors in ... -> The post @MainActor in Swift explained with code examples appeared first on SwiftLee.

## When It Makes Sense To "Block" The Main Thread

DevFeed: [When It Makes Sense To "Block" The Main Thread](<https://devfeed.tech/articles/when-it-makes-sense-to-block-the-main-thread-4316.md>)

Original publisher: [Read original article](<https://smashingmagazine.com/2026/07/when-makes-sense-block-main-thread/>)

Author: hello@smashingmagazine.com (Victor Ayomipo)

Published: 2026-07-17T08:00:00Z

Content type: article

Language: en

Sources: [Articles on Smashing Magazine -- For Web Designers And Developers](<https://devfeed.tech/sources/articles-on-smashing-magazine-for-web-designers-and-developers.md>)

Topics: [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Chrome extension](<https://devfeed.tech/topics/chrome-extension.md>), [Latency](<https://devfeed.tech/topics/latency.md>), [modern web development](<https://devfeed.tech/topics/modern-web-development.md>), [Chrome](<https://devfeed.tech/topics/chrome.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>)

Tags: [architecture](<https://devfeed.tech/tags/architecture.md>), [browser](<https://devfeed.tech/tags/browser.md>), [chrome](<https://devfeed.tech/tags/chrome.md>), [chrome-extension](<https://devfeed.tech/tags/chrome-extension.md>), [coding](<https://devfeed.tech/tags/coding.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [latency](<https://devfeed.tech/tags/latency.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [performance](<https://devfeed.tech/tags/performance.md>), [techniques](<https://devfeed.tech/tags/techniques.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

This article examines when blocking the browser's main thread can be faster than transferring work to a background worker. Using a Chrome screenshot extension as an example, it explains how serialization, copying, and deserialization can introduce enough latency to outweigh the responsiveness benefits of offloading computation.

### Source excerpt

The common rule of thumb is to never "block" the browser's main thread when running JavaScript tasks. But is this a hard rule? Victor Ayomipo describes a use case he encountered involving a screenshot extension where he made an exception to the rule and decided that blocking the main thread was absolutely the right thing to do.

## Releasing Execution Contexts

DevFeed: [Releasing Execution Contexts](<https://devfeed.tech/articles/releasing-execution-contexts-22337.md>)

Original publisher: [Read original article](<https://crystal-lang.org/2026/07/12/releasing-execution-contexts/>)

Author: Julien Portalier

Published: 2026-07-12T00:00:00Z

Content type: release

Language: en

Sources: [Crystal](<https://devfeed.tech/sources/crystal.md>)

Topics: [Crystal](<https://devfeed.tech/topics/crystal.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [context](<https://devfeed.tech/topics/context.md>), [cpu](<https://devfeed.tech/topics/cpu.md>)

Tags: [concurrent](<https://devfeed.tech/tags/concurrent.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [multithreading](<https://devfeed.tech/tags/multithreading.md>), [parallelism](<https://devfeed.tech/tags/parallelism.md>), [threads](<https://devfeed.tech/tags/threads.md>)

### AI overview

Crystal is introducing Execution Contexts, an interface for orchestrating fibers across one or more threads. The article describes concurrent and parallel contexts, configurable parallelism, and execution across CPU cores while preserving a single-threaded default.

### Source excerpt

Two and a half years ago, with the invaluable support from 84codes, we re-examined the multithreading model inherited from Crystal 0.28 (preview MT).

## Exploring PausableComposition internals in Jetpack Compose

DevFeed: [Exploring PausableComposition internals in Jetpack Compose](<https://devfeed.tech/articles/exploring-pausablecomposition-internals-in-jetpack-compose-25718.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/exploring-pausablecomposition-internals-in-jetpack-compose/>)

Author: Shreyas Patil

Published: 2025-07-14T05:34:31Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [code](<https://devfeed.tech/tags/code.md>), [compose](<https://devfeed.tech/tags/compose.md>), [declarative](<https://devfeed.tech/tags/declarative.md>), [internals](<https://devfeed.tech/tags/internals.md>), [jank](<https://devfeed.tech/tags/jank.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [performance](<https://devfeed.tech/tags/performance.md>), [performance-optimization](<https://devfeed.tech/tags/performance-optimization.md>), [ui](<https://devfeed.tech/tags/ui.md>), [uiux](<https://devfeed.tech/tags/uiux.md>)

### AI overview

This article explores the internals of PausableComposition, an internal API introduced in Compose 1.9.X. It explains how composition can be divided into smaller pieces and prepared asynchronously to reduce main-thread work and help prevent dropped frames during scrolling.

### Source excerpt

Explore the internals of PausableComposition in Jetpack Compose. Learn how Compose manages state and effects when a composition is paused or resumed.

## Giving V8 a Heads-Up: Faster JavaScript Startup with Explicit Compile Hints

DevFeed: [Giving V8 a Heads-Up: Faster JavaScript Startup with Explicit Compile Hints](<https://devfeed.tech/articles/giving-v8-a-heads-up-faster-javascript-startup-with-explicit-compile-hints-3521.md>)

Original publisher: [Read original article](<https://v8.dev/blog/explicit-compile-hints>)

Author: Marja Hölttä

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

Content type: article

Language: en

Sources: [V8](<https://devfeed.tech/sources/v8.md>)

Topics: [V8](<https://devfeed.tech/topics/v8.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Chrome](<https://devfeed.tech/topics/chrome.md>), [Web app](<https://devfeed.tech/topics/webapp.md>), [Web Development](<https://devfeed.tech/topics/web-development.md>)

Tags: [chrome](<https://devfeed.tech/tags/chrome.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [performance](<https://devfeed.tech/tags/performance.md>), [speed](<https://devfeed.tech/tags/speed.md>), [thread](<https://devfeed.tech/tags/thread.md>), [web-app](<https://devfeed.tech/tags/web-app.md>), [web-developers](<https://devfeed.tech/tags/web-developers.md>)

### AI overview

The article explains how V8 chooses between eager and deferred JavaScript compilation and how Explicit Compile Hints can improve startup performance. It describes Chrome 136 support for selecting individual files for eager compilation, while warning that compiling too much can increase time and memory use.

### Source excerpt

Getting JavaScript running fast is key for a responsive web app. Even with V8's advanced optimizations, parsing and compiling critical JavaScript during startup can still create performance bottlenecks. Knowing which JavaScript functions to compile during the initial script compilation can speed up web page loading. When processing a script loaded from the network, V8 has to choose for each function: either compile it immediately ("eagerly") or defer this process. If a function that hasn't been compiled is later called, V8 must then compile it on demand. If a JavaScript function ends up being called during page load, compiling it eagerly is beneficial, because: During the initial processing of the script, we need to do at least a lightweight parse to find the function end. In JavaScript, finding the function end requires parsing the full syntax (there are no shortcuts where we could count the curly braces - the grammar is too complex). Doing the lightweight parsing first and the actual parsing afterwards is duplicate work. If we decide to compile a function eagerly, the work happens on a background thread, and parts of it are interleaved with loading the script from the network. If we instead compile the function only when it's being called, it's too late to parallelize work, since the main thread cannot proceed until the function is compiled. You can read more about how V8 parses and compiles JavaScript in here. Many web pages would benefit from selecting the correct functions for eager compilation. For example, in our experiment with popular web pages, 17 out of 20 showed improvements, and the average foreground parse and compile times reduction was 630 ms. We're developing a feature, Explicit Compile Hints, which allows web developers to control which JavaScript files and functions are compiled eagerly. Chrome 136 is now shipping a version where you can select individual files for eager compilation. This version is particularly useful if you have a "core file" wh

## Understanding Dispatchers: Main and Main.immediate

DevFeed: [Understanding Dispatchers: Main and Main.immediate](<https://devfeed.tech/articles/understanding-dispatchers-main-and-main-immediate-25756.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/understanding-dispatchers-main-and-mainimmediate/>)

Author: Shreyas Patil

Published: 2025-04-02T12:22:06Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.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>), [android-apps](<https://devfeed.tech/tags/android-apps.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [coroutines-flow](<https://devfeed.tech/tags/coroutines-flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-beginner](<https://devfeed.tech/tags/kotlin-beginner.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [multithreading](<https://devfeed.tech/tags/multithreading.md>), [reactive-programming](<https://devfeed.tech/tags/reactive-programming.md>), [threadpools](<https://devfeed.tech/tags/threadpools.md>), [threads](<https://devfeed.tech/tags/threads.md>)

### AI overview

A deep dive into Kotlin coroutine dispatchers on Android, explaining the difference between Dispatchers.Main and Dispatchers.Main.immediate. It describes how HandlerContext dispatches work and when execution is posted to the main thread or performed synchronously on the current thread.

### Source excerpt

A deep dive into Kotlin Coroutine Dispatchers. Understand the subtle but important difference between Dispatchers.Main and Dispatchers.Main.immediate in Android.

## Coroutines and Dispatchers

DevFeed: [Coroutines and Dispatchers](<https://devfeed.tech/articles/coroutines-and-dispatchers-22871.md>)

Original publisher: [Read original article](<https://medium.com/mindorks/coroutines-and-dispatchers-b559094b828e?source=rss----f1a763fc7443---4>)

Author: Bigyan Thapa

Published: 2024-10-16T06:48:00Z

Content type: tutorial

Language: en

Sources: [Mindorks - Medium](<https://devfeed.tech/sources/mindorks-medium.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.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>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [best-practices](<https://devfeed.tech/tags/best-practices.md>), [code-quality](<https://devfeed.tech/tags/code-quality.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dispatcher](<https://devfeed.tech/tags/dispatcher.md>), [extension](<https://devfeed.tech/tags/extension.md>), [extension-function](<https://devfeed.tech/tags/extension-function.md>), [io](<https://devfeed.tech/tags/io.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>)

### AI overview

This tutorial explains how Android ViewModel coroutines use viewModelScope and how to select Dispatchers.IO, Dispatchers.Default, or Dispatchers.Main for I/O, CPU-intensive, and UI work. It also presents ViewModel extension functions and an overloaded function to standardize coroutine launching.

### Source excerpt

In Android development, coroutines are commonly launched from ViewModel classes using viewModelScope. The typical usage looks like this: viewModelScope.launch { // ... implementation } In Android development, coroutines are commonly launched from ViewModel classes using viewModelScope. The typical usage looks like this: viewModelScope.launch { // ... implementation } By default, if a dispatcher is not specified, any coroutine launched in viewModelScope will run on the main thread. However, in most use cases, we launch these coroutines to perform background tasks, such as -- making API calls, or database operations. To ensure these tasks run in the background thread, it is essential to specify an appropriate dispatcher: I/O tasks should use Dispatchers.IO CPU-intensive tasks should use Dispatchers.Default UI updates should use Dispatchers.Main For example, to run an I/O task, we can specify the dispatcher like this: viewModelScope.launch(Dispatchers.IO) { // ...implementation }Optimizing Coroutine Launching To streamline coroutine launching, we can create extension functions on ViewModel that automatically use the specified dispatcher by default. Step 1: Create Extension Functions We can define extension functions for different dispatchers: kotlin fun ViewModel.launchIO(block: suspend CoroutineScope.() -> Unit) { viewModelScope.launch(Dispatchers.IO, block = block) } fun ViewModel.launchDefault(block: suspend CoroutineScope.() -> Unit) { viewModelScope.launch(Dispatchers.Default, block = block) } fun ViewModel.launchMain(block: suspend CoroutineScope.() -> Unit) { viewModelScope.launch(Dispatchers.Main, block = block) }Step 2: Use the Extension Functions You can now use these extension functions in your ViewModel as follows: class MyViewModel : ViewModel() { fun fetchData() { launchIO { // ... implementation } } } Benefits Consistency: These extension functions maintain consistent coroutine usage for specific tasks. Readability: The function names clearly indicate their p

## Introducing Nuxt Scripts

DevFeed: [Introducing Nuxt Scripts](<https://devfeed.tech/articles/introducing-nuxt-scripts-3411.md>)

Original publisher: [Read original article](<https://nuxt.com/blog/nuxt-scripts>)

Published: 2024-08-20T00:00:00Z

Content type: article

Language: en

Sources: [The Nuxt Blog](<https://devfeed.tech/sources/the-nuxt-blog.md>)

Topics: [Nuxt.js](<https://devfeed.tech/topics/nuxt.md>), [Developer experience](<https://devfeed.tech/topics/developer-experience.md>), [Core Web Vitals](<https://devfeed.tech/topics/core-web-vitals.md>), [Security](<https://devfeed.tech/topics/security.md>), [Server-side rendering](<https://devfeed.tech/topics/server-side-rendering.md>), [Web](<https://devfeed.tech/topics/web.md>)

Tags: [core-web-vitals](<https://devfeed.tech/tags/core-web-vitals.md>), [developer](<https://devfeed.tech/tags/developer.md>), [developer-experience](<https://devfeed.tech/tags/developer-experience.md>), [interaction-to-next-paint](<https://devfeed.tech/tags/interaction-to-next-paint.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [nuxt](<https://devfeed.tech/tags/nuxt.md>), [performance](<https://devfeed.tech/tags/performance.md>), [privacy](<https://devfeed.tech/tags/privacy.md>), [release](<https://devfeed.tech/tags/release.md>), [security](<https://devfeed.tech/tags/security.md>), [ssr](<https://devfeed.tech/tags/ssr.md>), [third-party](<https://devfeed.tech/tags/third-party.md>), [vue](<https://devfeed.tech/tags/vue.md>), [web](<https://devfeed.tech/tags/web.md>)

### AI overview

Nuxt Scripts enters public beta as a Nuxt module for managing and optimizing third-party scripts. Developed with Google's Chrome Aurora team, it aims to improve performance, privacy, security, and developer experience while addressing script loading, SSR safety, hydration, and Core Web Vitals issues.

### Source excerpt

Nuxt Scripts provides better performance, privacy, security, and developer experience for third-party scripts.

## Kotlin Coroutines dispatchers

DevFeed: [Kotlin Coroutines dispatchers](<https://devfeed.tech/articles/kotlin-coroutines-dispatchers-39236.md>)

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

Published: 2024-07-01T00:00:00Z

Content type: tutorial

Language: en

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

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

Tags: [blocking](<https://devfeed.tech/tags/blocking.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dispatcher](<https://devfeed.tech/tags/dispatcher.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [ui](<https://devfeed.tech/tags/ui.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

This tutorial explains Kotlin Coroutines dispatchers, which determine the thread or thread pool where coroutines start and resume. It covers the default dispatcher, limiting dispatcher parallelism, and the Main dispatcher for UI-related work, with a comparison to RxJava schedulers.

### Source excerpt

Where we should use each dispatcher from the Kotlin Coroutines library.

## ANR internals: touch dispatching through the view hierarchy

DevFeed: [ANR internals: touch dispatching through the view hierarchy](<https://devfeed.tech/articles/anr-internals-touch-dispatching-through-the-view-hierarchy-25618.md>)

Original publisher: [Read original article](<https://blog.p-y.wtf/anr-internals-touch-dispatching-through-the-view-hierarchy>)

Author: Pierre-Yves Ricau

Published: 2023-09-14T16:32:24Z

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>), [ui](<https://devfeed.tech/topics/ui.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [anr](<https://devfeed.tech/tags/anr.md>), [compose](<https://devfeed.tech/tags/compose.md>), [deep-dive](<https://devfeed.tech/tags/deep-dive.md>), [internals](<https://devfeed.tech/tags/internals.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [performance](<https://devfeed.tech/tags/performance.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

This first article in a series on Android ANR internals examines how touch and input events move through the view hierarchy. It explains that input dispatching can trigger an ANR when an app does not respond within five seconds, and compares traditional view listener dispatch with Compose click-lambda dispatch.

### Source excerpt

I'm writing a blog series on ANR internals, where I'll use ANRs as an excuse to learn more about how various parts of Android work. This first article is focused on touch dispatching through the view hierarchy. ANR triggers How is an "Application No...

## Sleepless Concurrency: delay() vs. Thread.sleep()

DevFeed: [Sleepless Concurrency: delay() vs. Thread.sleep()](<https://devfeed.tech/articles/sleepless-concurrency-delay-vs-thread-sleep-25750.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/sleepless-concurrency-delay-vs-threadsleep/>)

Author: Shreyas Patil

Published: 2023-07-31T04:39:30Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Programming](<https://devfeed.tech/topics/programming.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [blocking](<https://devfeed.tech/tags/blocking.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [multithreading](<https://devfeed.tech/tags/multithreading.md>), [threading](<https://devfeed.tech/tags/threading.md>)

### AI overview

This tutorial explains how Kotlin coroutines implement delay() on the JVM and contrasts its non-blocking behavior with Java's blocking Thread.sleep(). A single-thread example shows that delay() allows concurrent coroutines to progress, while Thread.sleep() makes the second coroutine wait and roughly doubles total execution time.

### Source excerpt

Explore the difference between delay() and Thread.sleep() in Kotlin. Understand how non-blocking concurrency works from a platform perspective.

## I still see LiveData - where are the Flows?

DevFeed: [I still see LiveData - where are the Flows?](<https://devfeed.tech/articles/i-still-see-livedata-where-are-the-flows-32059.md>)

Original publisher: [Read original article](<https://www.maiatoday.net/p/i-still-see-livedata-where-are-the-flows/>)

Published: 2023-07-30T19:38:36Z

Content type: opinion

Language: en

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

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [live-data](<https://devfeed.tech/tags/live-data.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [network](<https://devfeed.tech/tags/network.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

The article argues that LiveData is appropriate for observing UI state but is a poor fit for repositories because it is tied to the Android lifecycle and always runs on the main thread. It recommends using Kotlin Flows, particularly in repositories, because they support configurable dispatchers, richer operators, and multiplatform projects.

### Source excerpt

Hammer and nail There is no doubt LiveData is an easy, lifecycle safe way to observe some state which needs to be displayed on the UI. It is just so easy to create and easy to update. It is easy to observe. I think that may be why people use it everywhere where they need a simple observation. This ok, no guilt, no harm .... for the UI layers .... but there are better solutions for domain and data layers. This is not the first time this topic has come up yet I still see Live Data in a repository offered as a good solution from time to time, in blog posts, samples and in books. I think it is a case of people think they only have a LiveData hammer. There are infact pitfalls if you use LiveData in a repository. I think it's an anti-pattern. But why not LiveData is lifecycle aware - do we need this in our repository? Repostitories are typically provided by dependency injection, they could be singletons and they don't need to know about the Android lifecycle. LiveData always runs on the main thread, you can't change this. This is not what we want in a repository. Repositories often work with different data sources which could involve network or disk access tasks. I would argue that you need to be able to run these kinds of tasks on the correct dispatcher if your libraries do not already do this. This is the deal breaker for me because you can cause jank in the UI if you do this incorrectly. LiveData does have some capabilities to combine and convert LiveData variables with MediatorLiveData but flows provide a wide variety of elegant operators to choose from. This is probably not a solid argument more a case of convenience. Lastly, one of the biggest reasons after the main thread argument, why I would advocate for converting all of the LiveData use to flows: flows are part of the Kotlin coroutines library. This means they run on any platform where Kotlin coroutines run. You can use them in a multiplatform project. Or to put it differently, if you use flows in your repository i

## How Android Memory Leaks Cause Jank, Freezes, and ANRs

DevFeed: [How Android Memory Leaks Cause Jank, Freezes, and ANRs](<https://devfeed.tech/articles/freezes-anrs-check-memory-leaks-25624.md>)

Original publisher: [Read original article](<https://blog.p-y.wtf/freezes-anrs-check-memory-leaks>)

Author: Pierre-Yves Ricau

Published: 2023-07-20T22:09:53Z

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>), [Memory Leaks](<https://devfeed.tech/topics/memory-leaks.md>), [Latency](<https://devfeed.tech/topics/latency.md>), [navigation](<https://devfeed.tech/topics/navigation.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [jank](<https://devfeed.tech/tags/jank.md>), [latency](<https://devfeed.tech/tags/latency.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [memory-leak](<https://devfeed.tech/tags/memory-leak.md>), [memory-leaks](<https://devfeed.tech/tags/memory-leaks.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [outofmemory](<https://devfeed.tech/tags/outofmemory.md>), [performance](<https://devfeed.tech/tags/performance.md>)

### AI overview

This article explains how Android memory leaks can cause jank, freezes, and ANRs rather than immediate crashes. It describes tracking memory usage per navigation, correlating memory growth with navigation latency, and how garbage collection blocking the main thread affects UI responsiveness near the app memory limit.

### Source excerpt

In this article, I show how Android memory leaks lead to jank, freezes and ANRs more often than they lead to OutOfMemoryError crashes. Navigation Latency At Square, we've been tracking a User-Centric performance metric: Interaction Latency. We track ...

## Node.js 20.0.0 (Current)

DevFeed: [Node.js 20.0.0 (Current)](<https://devfeed.tech/articles/node-js-20-0-0-current-2702.md>)

Original publisher: [Read original article](<https://nodejs.org/en/blog/release/v20.0.0>)

Published: 2023-04-18T16:07:46Z

Content type: release

Language: en

Sources: [Node.js Blog](<https://devfeed.tech/sources/node-js-blog.md>)

Topics: [Node.js](<https://devfeed.tech/topics/node-js.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Ada](<https://devfeed.tech/topics/ada.md>), [Chromium](<https://devfeed.tech/topics/chromium.md>)

Tags: [chromium](<https://devfeed.tech/tags/chromium.md>), [cross-platform](<https://devfeed.tech/tags/cross-platform.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [json](<https://devfeed.tech/tags/json.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [node](<https://devfeed.tech/tags/node.md>), [node-js](<https://devfeed.tech/tags/node-js.md>), [open-source](<https://devfeed.tech/tags/open-source.md>), [performance](<https://devfeed.tech/tags/performance.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

Node.js 20.0.0 introduces an experimental Permission Model for restricting access to resources such as the file system, child-process spawning, and worker-thread creation. The release also moves ESM loader hooks to a dedicated thread, updates V8 to 11.3, stabilizes the test_runner module, integrates Ada 2.0 for faster URL parsing, and changes how single-executable applications are built.

### Source excerpt

Node.js® is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.

## Mastering Android App Performance: Analyzing Bottlenecks with Perfetto 🚦

DevFeed: [Mastering Android App Performance: Analyzing Bottlenecks with Perfetto 🚦](<https://devfeed.tech/articles/mastering-android-app-performance-analyzing-bottlenecks-with-perfetto-25737.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/mastering-android-app-performance-analyzing-bottlenecks-with-perfetto/>)

Author: Shreyas Patil

Published: 2023-03-13T13:00:39Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [tracing](<https://devfeed.tech/topics/tracing.md>), [Traces](<https://devfeed.tech/topics/traces.md>), [Emulator](<https://devfeed.tech/topics/emulator.md>), [browser](<https://devfeed.tech/topics/browser.md>), [Terminal](<https://devfeed.tech/topics/terminal.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [app-performance](<https://devfeed.tech/tags/app-performance.md>), [browser](<https://devfeed.tech/tags/browser.md>), [commands](<https://devfeed.tech/tags/commands.md>), [emulator](<https://devfeed.tech/tags/emulator.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [perfetto](<https://devfeed.tech/tags/perfetto.md>), [performance](<https://devfeed.tech/tags/performance.md>), [profiling](<https://devfeed.tech/tags/profiling.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [tracing](<https://devfeed.tech/tags/tracing.md>)

### AI overview

A practical Android tutorial on using Perfetto system tracing to investigate UI slowness and jank. It creates a sample app with deliberately heavy main-thread work, records a trace, and examines the resulting timelines to locate performance bottlenecks.

### Source excerpt

Master Android app performance profiling with Perfetto. Learn how to identify and fix UI janks and bottlenecks using system tracing.

## OkLayoutInflater: Improving Android XML Layout Inflation with Parallel Coroutines

DevFeed: [OkLayoutInflater: Improving Android XML Layout Inflation with Parallel Coroutines](<https://devfeed.tech/articles/oklayoutinflater-37405.md>)

Original publisher: [Read original article](<https://medium.com/okcredit/oklayoutinflater-3c5cd93c6ebc?source=rss----40ea5327aac7---4>)

Author: Anjal Saneen

Published: 2022-10-26T01:27:02Z

Content type: tutorial

Language: en

Sources: [OkCredit - Medium](<https://devfeed.tech/sources/okcredit-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [XML](<https://devfeed.tech/topics/xml.md>), [Code](<https://devfeed.tech/topics/code.md>), [Parsing](<https://devfeed.tech/topics/parsing.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [IO](<https://devfeed.tech/topics/io.md>), [callback](<https://devfeed.tech/topics/callback.md>), [interface](<https://devfeed.tech/topics/interface.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>), [anr](<https://devfeed.tech/tags/anr.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [file](<https://devfeed.tech/tags/file.md>), [io](<https://devfeed.tech/tags/io.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [memory](<https://devfeed.tech/tags/memory.md>), [mobile-app-development](<https://devfeed.tech/tags/mobile-app-development.md>), [parallelism](<https://devfeed.tech/tags/parallelism.md>), [parsing](<https://devfeed.tech/tags/parsing.md>), [performance](<https://devfeed.tech/tags/performance.md>)

### AI overview

This tutorial explains how OkLayoutInflater addresses limitations in AndroidX AsyncLayoutInflater. It describes the existing implementation's sequential background inflation and presents a coroutine-based approach intended to use parallelism based on CPU cores, helping recycler view items load and scroll faster.

### Source excerpt

The loading of large XML layouts is one of the major performance bottlenecks in android. Loading XML layout into memory through IO operations and parsing views through reflection can be expensive. This is especially true when the XML file is too large or when initializing the layout view takes a while. We know that when the main thread performs some time-consuming operations, it may cause the page to freeze, and even more, serious ANR may occur. Androidx AsyncLayoutInflater helps to load those layouts asynchronously. However, we found that it has some limitations. The goal of this blog post is to explain how OkLayoutInflater addresses these limitations. Source code analysis of AndroidX AsyncLayoutInflater https://android.googlesource.com/platform/frameworks/support/+/89f7eba/v4/java/android/support/v4/view/AsyncLayoutInflater.java Source code is short and easy to understand with only a few lines of code. In the inflate method, it creates an InflateRequest object and stores variables such as resid, parent, callback, etc. Then it calls enqueue to add the request to the InflateThread queue. The main purpose of InflateThread is to add requests to the blocking queue and perform BasicInflater.inflate operations in order. Regardless of inflating success or failure, the request message will be sent to the main thread for processing. The BasicInflater Inherited from LayoutInflater. In OnCreateView these prefixes are loaded on the layout. At last, mHandlerCallback implements handleMessage which executes the operation on main thread, and there is a fallback mechanism, that is when the child thread inflates fails. it will continue to inflate on the main thread, and finally, gives a callback to the main thread through the OnInflateFinishedListener interface. The limitations of AsyncLayoutInflater and how we improve it Single thread to do all the inflate work AsyncLayoutInflater has this major limitation. This was the main reason for creating a custom implementation. One of our r

## How @MainActor works

DevFeed: [How @MainActor works](<https://devfeed.tech/articles/how-mainactor-works-21713.md>)

Original publisher: [Read original article](<https://oleb.net/2022/how-mainactor-works/>)

Author: Ole Begemann

Published: 2022-05-05T13:52:42Z

Content type: tutorial

Language: en

Sources: [Ole Begemann](<https://devfeed.tech/sources/ole-begemann.md>)

Topics: [Swift](<https://devfeed.tech/topics/swift.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Protocol (disambiguation)](<https://devfeed.tech/topics/protocol.md>)

Tags: [await](<https://devfeed.tech/tags/await.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [executor](<https://devfeed.tech/tags/executor.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [protocol](<https://devfeed.tech/tags/protocol.md>), [swift](<https://devfeed.tech/tags/swift.md>)

### AI overview

This tutorial explains how Swift's @MainActor works by reimplementing it in simplified form. It describes the roles of global actors and custom executors, including how a custom serial executor can run jobs on the main dispatch queue.

### Source excerpt

@MainActor is a Swift annotation to coerce a function to always run on the main thread and to enable the compiler to verify this. How does this work? In this article, I'm going to reimplement @MainActor in a slightly simplified form for illustration purposes, mainly to show how little "magic" there is to it. The code of the real implementation in the Swift standard library is available in the Swift repository. @MainActor relies on two Swift features, one of them unofficial: global actors and custom executors. Global actors MainActor is a global actor. That is, it provides a single actor instance that is shared between all places in the code that are annotated with @MainActor. All global actors must implement the shared property that's defined in the GlobalActor protocol (every global actor implicitly conforms to this protocol): @globalActor final actor MyMainActor { // Requirements from the implicit GlobalActor conformance typealias ActorType = MyMainActor static var shared: ActorType = MyMainActor() // Don't allow others to create instances private init() {} } At this point, we have a global actor that has the same semantics as any other actor. That is, functions annotated with @MyMainActor will run on a thread in the cooperative thread pool managed by the Swift runtime. To move the work to the main thread, we need another concept, custom executors. Executors A bit of terminology: The compiler splits async code into jobs. A job roughly corresponds to the code from one await (= potential suspension point) to the next. The runtime submits each job to an executor. The executor is the object that decides in which order and in which context (i.e. which thread or dispatch queue) to run the jobs. Swift ships with two built-in executors: the default concurrent executor, used for "normal", non-actor-isolated async functions, and a default serial executor. Every actor instance has its own instance of this default serial executor and runs its code on it. Since the serial exec

## Tracing main thread messages

DevFeed: [Tracing main thread messages](<https://devfeed.tech/articles/tracing-main-thread-messages-25631.md>)

Original publisher: [Read original article](<https://blog.p-y.wtf/tracing-main-thread-messages>)

Author: Pierre-Yves Ricau

Published: 2022-01-27T19:53:56Z

Content type: tutorial

Language: en

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

Topics: [tracing](<https://devfeed.tech/topics/tracing.md>), [Android](<https://devfeed.tech/topics/android.md>), [Logging](<https://devfeed.tech/topics/logging.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [logger](<https://devfeed.tech/tags/logger.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [perfetto](<https://devfeed.tech/tags/perfetto.md>), [performance](<https://devfeed.tech/tags/performance.md>), [tracing](<https://devfeed.tech/tags/tracing.md>)

### AI overview

This tutorial explains how to inspect Android main-thread activity in Perfetto traces. It uses the seldom-used Looper.setMessageLogging() API to log message dispatches and adds trace sections for each main-thread message with the AndroidX tracing library.

### Source excerpt

👋 Hi, this is P.Y., I work as an Android Engineer at Block, the non-fungible company formerly known as Square. I spend a lot of time focusing on performance and try to share my experience with deep-d

## Why I use Linux

DevFeed: [Why I use Linux](<https://devfeed.tech/articles/why-i-use-linux-41488.md>)

Original publisher: [Read original article](<https://chollinger.com/blog/2020/12/why-i-use-linux/>)

Author: Christian Hollinger

Published: 2020-12-21T00:00:00Z

Content type: article

Language: en

Sources: [Christian Hollinger](<https://devfeed.tech/sources/christian-hollinger.md>)

Topics: [Linux](<https://devfeed.tech/topics/linux.md>), [data-engineering](<https://devfeed.tech/topics/data-engineering.md>), [Development](<https://devfeed.tech/topics/development.md>), [Operating system](<https://devfeed.tech/topics/operating-system.md>), [Kernel](<https://devfeed.tech/topics/kernel.md>), [Hardware](<https://devfeed.tech/topics/hardware.md>), [Security](<https://devfeed.tech/topics/security.md>)

Tags: [bsd](<https://devfeed.tech/tags/bsd.md>), [data-engineering](<https://devfeed.tech/tags/data-engineering.md>), [development](<https://devfeed.tech/tags/development.md>), [distributed](<https://devfeed.tech/tags/distributed.md>), [gnu](<https://devfeed.tech/tags/gnu.md>), [hardware](<https://devfeed.tech/tags/hardware.md>), [kernel](<https://devfeed.tech/tags/kernel.md>), [linux](<https://devfeed.tech/tags/linux.md>), [mac](<https://devfeed.tech/tags/mac.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [os](<https://devfeed.tech/tags/os.md>), [programming](<https://devfeed.tech/tags/programming.md>), [security](<https://devfeed.tech/tags/security.md>), [software](<https://devfeed.tech/tags/software.md>), [windows](<https://devfeed.tech/tags/windows.md>)

### AI overview

The article explains why the author uses GNU/Linux for development and data engineering. It highlights Linux's stability, customizability, software availability, auditability, security attention, and similarity to production server environments, then discusses how operating-system processes and hardware affect computationally intensive distributed work.

### Source excerpt

One question I do get in earnest quite frequently is why I put up with running GNU/Linux distributions for development work. An attempt at a simple response.

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

## Litmus-Testing Kotlin's Many Memory Models

DevFeed: [Litmus-Testing Kotlin's Many Memory Models](<https://devfeed.tech/articles/litmus-testing-kotlin-s-many-memory-models-20946.md>)

Original publisher: [Read original article](<https://jakewharton.com/litmus-testing-kotlins-many-memory-models/>)

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

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [memory](<https://devfeed.tech/tags/memory.md>), [tests](<https://devfeed.tech/tags/tests.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

The article examines how Kotlin's JavaScript, JVM, and native compiler backends implement different memory models. It explains a Kotlin/Native issue caused by sharing an unannotated empty array across threads and recommends running tests on both the main and background threads to prevent regressions.

### Source excerpt

When writing multiplatform code, Kotlin's three compiler backends each have different memory models which must be considered. JavaScript is single-threaded so you really can do no wrong. The JVM model is arguably too permissive where you can do incorrect things and have them work 99.9% of the time. When targeting native, Kotlin enforces some invariants which helps prevent you from those 0.1% bugs that crop up in the JVM. I've been porting the AndroidX collection library to Kotlin multiplatform to experiment with binary compatibility, performance, tooling, and the different memory models. The library consists of mutable, single-threaded data structures. This should mean the different memory models never come into play. But weirdly they do, and let's look at how. On Deck The Kotlin standard library contains general-purpose collections like lists, sets, and maps in both mutable and read-only form. Kotlin 1.3.70 added another collection, ArrayDeque, a "double-ended queue" for efficient stacks and queues. During the 1.3.70 EAP, Kevin Galligan opened an issue where ArrayDeque could only be instantiated on the main thread and not a background thread when targeting Kotlin/Native. At the time I didn't read into it, but as I was porting these collections it came to mind. The underlying cause was that the implementation relied on a top-level val for a shared, empty array when the collection was empty. Arrays are fixed-length, so an empty array is effectively immutable and thus can be shared by all empty collections. But that seems fine? It is fine for Kotlin/JS and Kotlin/JVM but Kotlin/Native is different here. By default, Kotlin/Native only allows the main thread to access top-level vals. If you want to access the value from multiple threads (potentially concurrently) you must choose whether you want thread-local or shared-but-immutable behavior with an annotation. ArrayDeque's empty array was missing this annotation. As it turns out, my collections had the exact same issue!

## D8 Optimization: Assertions

DevFeed: [D8 Optimization: Assertions](<https://devfeed.tech/articles/d8-optimization-assertions-20929.md>)

Original publisher: [Read original article](<https://jakewharton.com/d8-optimization-assertions/>)

Published: 2020-03-25T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Java](<https://devfeed.tech/topics/java.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [java](<https://devfeed.tech/tags/java.md>), [jvm](<https://devfeed.tech/tags/jvm.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

This article explains how D8 and R8 optimize Java assert statements in Android applications. Because Android does not support enabling Java assertions, D8 can remove the assertion check and its dependent expressions, allowing dead-code elimination. The example uses an assertion to enforce main-thread access when generating unique IDs, and the article connects this optimization to R8's SSA-based analysis.

### Source excerpt

Note: This post is part of a series on D8 and R8, Android's new dexer and optimizer, respectively. For an intro to D8 read "Android's Java 8 support". For an intro to R8 read "R8 Optimization: Staticization". The assert keyword is quirky Java language syntax used for testing invariants. That is: things you expect to always be true. Its syntax has two forms: assert <bool-expression>; assert <bool-expression> : <expression>; The first expression will only be evaluated at runtime if the -ea (enable assertions) flag is set on the JVM. The second expression, if present, is used as the argument to the AssertionError constructor that's thrown if the first expression returns false. As an Android developer you might not be too familiar with assert. This is because every Android app runs on a VM which is forked from a shared "zygote" process which has assertions disabled. Thus, even if you put an assert in your code, there is no way to actually enable it. So why bother talking about it? Well it turns out they're about to become useful on Android for the first time! Today's behavior assert statements guard things which must always be true in order for your program to execute correctly. Let's write one. class IdGenerator { private int id = 0; int next() { assert Thread.currentThread() == Looper.getMainLooper().getThread(); return id++; } } This class creates unique IDs and guarantees they're unique by only allowing calls from the main thread. If this class was called concurrently from multiple threads you might see duplicate values. Sure it's a little contrived and there's things like @MainThread which is checked by Lint but we're focusing on assert so roll with it. The Null Data Flow Analysis post introduced the SSA form that R8 uses to eliminate branches of code which it can prove will never be executed. The SSA for the next() method when parsed from Java bytecode looks very roughly like this: D8 knows that Android does not support Java assertions. It will remove the check an

## Instrumenting Firebase Test Lab

DevFeed: [Instrumenting Firebase Test Lab](<https://devfeed.tech/articles/instrumenting-firebase-test-lab-15695.md>)

Original publisher: [Read original article](<https://developer.squareup.com/blog/instrumenting-firebase-test-lab>)

Author: P-Y Ricau

Published: 2020-01-15T20:00:00Z

Content type: tutorial

Language: en

Sources: [Square Corner Blog](<https://devfeed.tech/sources/square-corner-blog-medium.md>), [Square Corner Blog RSS Feed](<https://devfeed.tech/sources/square-corner-blog-rss-feed.md>)

Topics: [Firebase](<https://devfeed.tech/topics/firebase.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Instrumentation](<https://devfeed.tech/topics/instrumentation.md>), [Android](<https://devfeed.tech/topics/android.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [automated](<https://devfeed.tech/tags/automated.md>), [ci](<https://devfeed.tech/tags/ci.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [exception](<https://devfeed.tech/tags/exception.md>), [firebase](<https://devfeed.tech/tags/firebase.md>), [instrumentation](<https://devfeed.tech/tags/instrumentation.md>), [java](<https://devfeed.tech/tags/java.md>), [junit](<https://devfeed.tech/tags/junit.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [test](<https://devfeed.tech/tags/test.md>), [testing](<https://devfeed.tech/tags/testing.md>), [tests](<https://devfeed.tech/tags/tests.md>), [video](<https://devfeed.tech/tags/video.md>)

### AI overview

This tutorial describes utilities Square built around Firebase Test Lab for Android instrumentation testing. It explains how uncaught exceptions on non-instrumentation threads can cause unhelpful test failures, and presents a JUnit run listener that reports those exceptions before the process terminates. It also discusses runner arguments and adding test names to Firebase Test Lab videos.

### Source excerpt

Automated testing with Firebase Test Lab at Square

[Next page](<https://devfeed.tech/tags/main-thread.md?cursor=WyIyMDIwLTAxLTE1VDIwOjAwOjAwKzAwOjAwIiwgImU3MzAxNTYwLTAzMzMtNDgyNC05YmY1LTViMzUzYzY3YWMwZCJd>)