# R8

Published articles for R8.

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

## Obfuscation Fundamentals: Applying ProGuard and R8 Protections to Android Code

DevFeed: [Obfuscation Fundamentals: Applying ProGuard and R8 Protections to Android Code](<https://devfeed.tech/articles/obfuscation-32342.md>)

Original publisher: [Read original article](<https://dustn.dev/page/presentations/2019-07-24-obfuscation-fundamentals/>)

Author: dustin@dustn.dev (Dustin Summers)

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

Content type: tutorial

Language: en

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

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [meetup](<https://devfeed.tech/tags/meetup.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [r8](<https://devfeed.tech/tags/r8.md>), [video](<https://devfeed.tech/tags/video.md>)

### AI overview

A presentation introducing obfuscation with ProGuard and R8, focused on applying protections to Android code. It explains how to diagnose the code entering and leaving these build tools.

### Source excerpt

This presentation was given at a MeetUp in DC. It corresponds to this series of blog posts, which is the first in a series to teach about Obfuscation/ProGuard/R8, and will primarily be centered around applying protections to Android Code. Tools such as R8 and ProGuard are available, but to many they are a black box that code goes into and stuff comes out. The following will demystify the black box, and teach developers how to properly diagnose the code going into and coming out of these build tools.

## Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer

DevFeed: [Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer](<https://devfeed.tech/articles/tinder-cuts-app-cold-starts-by-47-with-new-r8-configuration-analyzer-4241.md>)

Original publisher: [Read original article](<https://android-developers.googleblog.com/2026/08/tinder-app-cold-start-r8-configuration-analyzer.html>)

Author: Android Developers (noreply@blogger.com)

Published: 2026-08-18T18:00:00Z

Content type: article

Language: en

Sources: [Android Developers Blog](<https://devfeed.tech/sources/android-developers-blog.md>), [Android Developers Blog](<https://devfeed.tech/sources/android-developers-blog-2.md>)

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

Tags: [agentic](<https://devfeed.tech/tags/agentic.md>), [android](<https://devfeed.tech/tags/android.md>), [development](<https://devfeed.tech/tags/development.md>), [errors](<https://devfeed.tech/tags/errors.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>), [startup](<https://devfeed.tech/tags/startup.md>), [time](<https://devfeed.tech/tags/time.md>)

### AI overview

The article describes how Tinder used the R8 Configuration Analyzer to identify and remove keep-rule blockers in its Android application. The effort reduced cold-start time by 47%, app download size by 28.98% to 61.5 MB, and user-perceived ANRs by 28%.

### Source excerpt

Posted by Ajesh R Pai, Developer Relations Engineer, Ulises Uriel Verduzco Diaz, Software Engineer, Tinder, and Tracy Agyemang, Product Marketing Manager Tinder is on a mission to power and inspire real connections by making meeting easy and fun for every new generation of singles. However, as their Android application codebase grew in size, so did its complexity. Prior to their latest optimization efforts, approximately 70% of the application was not optimized, carrying 17 dex files,including three dedicated just to startup. Although they had enabled R8, much of its optimization potential was blocked due to keep rules, and the team was unable to identify which specific rules were preventing optimization. To reduce startup time and decrease user-perceived Application Not Responding (ANR) errors, Tinder turned to the new R8 Configuration Analyzer to tackle these challenges. By utilizing the R8 Configuration Analyzer, Tinder successfully identified and removed unintentional optimization blockers. The results were immediate and impactful: Tinder achieved a 47% reduction in app cold starts, shrank their app download size by 28.98% (down to 61.5 MB), and reduced user-perceived ANRs by 28%. Configuration analyzer The R8 Configuration Analyzer shows R8 optimization by tracking shrinking, optimization, and obfuscation scores to show available refinement areas. It shows the broad, redundant, or obsolete keep rules, including those from external libraries so that you can analyse the keep rule impact and refine the keep rules. Key metrics shown in Configuration Analyzer include: Shrinking Score: Code percentage available for R8 shrinking. Optimization Score: Code percentage open to optimization (for example, method inlining, horizontal class merging). Obfuscation Score: Percentage of classes, methods and fields that can be renamed by R8 to decrease size. Use the analyzer to audit keep rules and their impacts: Find broad rules: Narrow the scope of package-wide rules that restri

## Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer

DevFeed: [Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer](<https://devfeed.tech/articles/tinder-cuts-app-cold-starts-by-47-with-new-r8-configuration-analyzer-22698.md>)

Original publisher: [Read original article](<http://android-developers.googleblog.com/2026/08/tinder-app-cold-start-r8-configuration-analyzer.html>)

Author: Android Developers (noreply@blogger.com)

Published: 2026-08-18T18:00:00Z

Content type: article

Language: en

Sources: [Android Developers Blog](<https://devfeed.tech/sources/android-developers-blog-3.md>)

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Android](<https://devfeed.tech/topics/android.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [audit](<https://devfeed.tech/topics/audit.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [anr](<https://devfeed.tech/tags/anr.md>), [audit](<https://devfeed.tech/tags/audit.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [metrics](<https://devfeed.tech/tags/metrics.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

This developer case study explains how Tinder used the R8 Configuration Analyzer to identify and remove keep-rule blockers in its Android application. The reported results were a 47% reduction in cold-start time, a 28.98% reduction in download size to 61.5 MB, and a 28% reduction in user-perceived ANRs. The article also describes analyzer metrics for shrinking, optimization, and obfuscation, along with an R8 Analyzer skill for agentic development workflows.

### Source excerpt

Posted by Ajesh R Pai, Developer Relations Engineer, Ulises Uriel Verduzco Diaz, Software Engineer, Tinder, and Tracy Agyemang, Product Marketing Manager Tinder is on a mission to power and inspire real connections by making meeting easy and fun for every new generation of singles. However, as their Android application codebase grew in size, so did its complexity. Prior to their latest optimization efforts, approximately 70% of the application was not optimized, carrying 17 dex files,including three dedicated just to startup. Although they had enabled R8, much of its optimization potential was blocked due to keep rules, and the team was unable to identify which specific rules were preventing optimization. To reduce startup time and decrease user-perceived Application Not Responding (ANR) errors, Tinder turned to the new R8 Configuration Analyzer to tackle these challenges. By utilizing the R8 Configuration Analyzer, Tinder successfully identified and removed unintentional optimization blockers. The results were immediate and impactful: Tinder achieved a 47% reduction in app cold starts, shrank their app download size by 28.98% (down to 61.5 MB), and reduced user-perceived ANRs by 28%. Configuration analyzer The R8 Configuration Analyzer shows R8 optimization by tracking shrinking, optimization, and obfuscation scores to show available refinement areas. It shows the broad, redundant, or obsolete keep rules, including those from external libraries so that you can analyse the keep rule impact and refine the keep rules. Key metrics shown in Configuration Analyzer include: Shrinking Score: Code percentage available for R8 shrinking. Optimization Score: Code percentage open to optimization (for example, method inlining, horizontal class merging). Obfuscation Score: Percentage of classes, methods and fields that can be renamed by R8 to decrease size. Use the analyzer to audit keep rules and their impacts: Find broad rules: Narrow the scope of package-wide rules that restri

## App Hardening: One Obfuscation Pipeline Across Every Port

DevFeed: [App Hardening: One Obfuscation Pipeline Across Every Port](<https://devfeed.tech/articles/app-hardening-one-obfuscation-pipeline-across-every-port-19196.md>)

Original publisher: [Read original article](<https://www.codenameone.com/blog/app-hardening-cross-platform/>)

Author: Shai Almog

Published: 2026-08-15T00:00:00Z

Content type: article

Language: en

Sources: [CodeName One](<https://devfeed.tech/sources/codename-one.md>)

Topics: [obfuscation](<https://devfeed.tech/topics/obfuscation.md>), [cross-platform](<https://devfeed.tech/topics/cross-platform.md>), [Encryption](<https://devfeed.tech/topics/encryption.md>), [Security](<https://devfeed.tech/topics/security.md>), [Reverse Engineering](<https://devfeed.tech/topics/reverse-engineering.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [app](<https://devfeed.tech/tags/app.md>), [cross-platform](<https://devfeed.tech/tags/cross-platform.md>), [encryption](<https://devfeed.tech/tags/encryption.md>), [hardening](<https://devfeed.tech/tags/hardening.md>), [ios](<https://devfeed.tech/tags/ios.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [native](<https://devfeed.tech/tags/native.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [platform](<https://devfeed.tech/tags/platform.md>), [r8](<https://devfeed.tech/tags/r8.md>), [reverse-engineering](<https://devfeed.tech/tags/reverse-engineering.md>), [security](<https://devfeed.tech/tags/security.md>)

### AI overview

Codename One App Hardening applies one pre-build protection pipeline to a merged cross-platform application before it is split into Android, iOS, JavaScript, Windows, Linux, and desktop builds. It supports renaming, eligible string encryption, selected control-flow transformations, verification, and crash-report retracing, while acknowledging that reverse engineering cannot be made impossible.

### Source excerpt

Codename One App Hardening applies class and member renaming, string encryption, and platform-safe control-flow transforms before one application becomes Android, iOS, JavaScript, or native desktop output.

## The Hidden Costs of DIY Android App Security | Guardsquare

DevFeed: [The Hidden Costs of DIY Android App Security | Guardsquare](<https://devfeed.tech/articles/the-hidden-costs-of-diy-android-app-security-guardsquare-26305.md>)

Original publisher: [Read original article](<https://www.guardsquare.com/blog/diy-android-app-security-hidden-costs>)

Author: Michael Olechna - Product Marketing Manager

Published: 2026-07-28T13:00:55Z

Content type: opinion

Language: en

Sources: [Guardsquare Blog](<https://devfeed.tech/sources/guardsquare-blog.md>)

Topics: [Security](<https://devfeed.tech/topics/security.md>), [Android](<https://devfeed.tech/topics/android.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [obfuscation](<https://devfeed.tech/topics/obfuscation.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [dexguard](<https://devfeed.tech/tags/dexguard.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [open-source](<https://devfeed.tech/tags/open-source.md>), [protection](<https://devfeed.tech/tags/protection.md>), [r8](<https://devfeed.tech/tags/r8.md>), [security](<https://devfeed.tech/tags/security.md>), [thought-leadership](<https://devfeed.tech/tags/thought-leadership.md>), [threat-monitoring](<https://devfeed.tech/tags/threat-monitoring.md>)

### AI overview

The article argues that DIY Android app security built around open-source tools can leave important protection gaps. It explains that R8 helps compile and optimize Android applications but is not a complete security solution, lacking capabilities such as string encryption, API endpoint security, and control-flow obfuscation.

### Source excerpt

The DIY temptation to build with open-source is strong for mobile app developers. After all, their job is to build, secure, and design new applications, features, and architectures that benefit the users of their apps.

## How R8 made Kotlin Coroutines on Android 2x faster

DevFeed: [How R8 made Kotlin Coroutines on Android 2x faster](<https://devfeed.tech/articles/how-r8-made-kotlin-coroutines-on-android-2x-faster-22684.md>)

Original publisher: [Read original article](<http://android-developers.googleblog.com/2026/07/how-r8-made-kotlin-coroutines-2x-faster.html>)

Author: Android Developers (noreply@blogger.com)

Published: 2026-07-27T13:00:00Z

Content type: article

Language: en

Sources: [Android Developers Blog](<https://devfeed.tech/sources/android-developers-blog-3.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Android](<https://devfeed.tech/topics/android.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [Programming](<https://devfeed.tech/topics/programming.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [app-performance](<https://devfeed.tech/tags/app-performance.md>), [atomic](<https://devfeed.tech/tags/atomic.md>), [compose](<https://devfeed.tech/tags/compose.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [perfetto](<https://devfeed.tech/tags/perfetto.md>), [performance](<https://devfeed.tech/tags/performance.md>), [programming](<https://devfeed.tech/tags/programming.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

This article explains how R8 in AGP 9.2.0 optimizes Atomic*FieldUpdater calls into Unsafe variants, improving common operations by 2x to 4x. The optimization particularly benefits kotlinx.atomicfu and can make launching and cancelling Kotlin coroutines up to 2x faster. It also describes how coroutine overhead affected Jetpack Compose performance and how ART method traces helped identify bottlenecks.

### Source excerpt

Posted by Andrei Shikov, Senior Software Engineer, Android Toolkit and Jonathan Starup, Software Engineer, R8 Team Starting from AGP 9.2.0, R8 optimizes most Atomic*FieldUpdater calls into Unsafe variants that perform 2x to 4x better on common operations. This has a particularly large impact on the kotlinx.atomicfu library that implements atomics for kotlinx.coroutines, making launching and cancelling coroutines up to 2x faster. In order to get the benefits, update your AGP to 9.2.0 or above. With the majority of Android apps adopting Kotlin as their main language of choice, kotlinx.coroutines has become a de-facto standard for asynchronous programming. The library offers a well-designed and structured way of managing concurrent flows that is native to Kotlin. Jetpack Compose was no exception, adopting coroutines for managing pointer events, animations and other interactions. At the time of writing, most concurrent APIs in Compose call suspend functions under the hood and are launching and/or cancelling coroutines to handle updates. As the Compose team started to investigate performance, coroutines were discovered to be a bottleneck for many operations that happen outside of composition. As an example, 80% of the time spent on creating and updating Modifier.clickable was consumed by launching and cancelling internal coroutines that handled InteractionSource updates. Based on those observations, much of early performance work was focused on removing coroutines from the default path and delaying initialization until necessary. The cost of a coroutine The easiest way to analyze a function's internal behavior on Android is to capture an Android Runtime (ART) method trace. An ART method trace is a tool that records the execution flow of an app, showing exactly which methods are called, their order, and how much time is spent in each, allowing developers to identify performance bottlenecks. For an empty LaunchedEffect { } call, it would look something like this: LaunchedE

## How R8 made Kotlin Coroutines on Android 2x faster

DevFeed: [How R8 made Kotlin Coroutines on Android 2x faster](<https://devfeed.tech/articles/how-r8-made-kotlin-coroutines-on-android-2x-faster-4227.md>)

Original publisher: [Read original article](<https://android-developers.googleblog.com/2026/07/how-r8-made-kotlin-coroutines-2x-faster.html>)

Author: Android Developers (noreply@blogger.com)

Published: 2026-07-27T13:00:00Z

Content type: article

Language: en

Sources: [Android Developers Blog](<https://devfeed.tech/sources/android-developers-blog.md>), [Android Developers Blog](<https://devfeed.tech/sources/android-developers-blog-2.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Android](<https://devfeed.tech/topics/android.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [Programming](<https://devfeed.tech/topics/programming.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [app-performance](<https://devfeed.tech/tags/app-performance.md>), [atomic](<https://devfeed.tech/tags/atomic.md>), [compose](<https://devfeed.tech/tags/compose.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [performance](<https://devfeed.tech/tags/performance.md>), [programming](<https://devfeed.tech/tags/programming.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

This article explains how R8 optimization in AGP 9.2.0 improves Kotlin coroutines performance on Android. By optimizing AtomicFieldUpdater calls, the change makes launching and cancelling coroutines up to twice as fast, addressing coroutine-related bottlenecks in Jetpack Compose and other Android operations.

### Source excerpt

Posted by Andrei Shikov, Senior Software Engineer, Android Toolkit and Jonathan Starup, Software Engineer, R8 Team Starting from AGP 9.2.0, R8 optimizes most Atomic*FieldUpdater calls into Unsafe variants that perform 2x to 4x better on common operations. This has a particularly large impact on the kotlinx.atomicfu library that implements atomics for kotlinx.coroutines, making launching and cancelling coroutines up to 2x faster. In order to get the benefits, update your AGP to 9.2.0 or above. With the majority of Android apps adopting Kotlin as their main language of choice, kotlinx.coroutines has become a de-facto standard for asynchronous programming. The library offers a well-designed and structured way of managing concurrent flows that is native to Kotlin. Jetpack Compose was no exception, adopting coroutines for managing pointer events, animations and other interactions. At the time of writing, most concurrent APIs in Compose call suspend functions under the hood and are launching and/or cancelling coroutines to handle updates. As the Compose team started to investigate performance, coroutines were discovered to be a bottleneck for many operations that happen outside of composition. As an example, 80% of the time spent on creating and updating Modifier.clickable was consumed by launching and cancelling internal coroutines that handled InteractionSource updates. Based on those observations, much of early performance work was focused on removing coroutines from the default path and delaying initialization until necessary. The cost of a coroutine The easiest way to analyze a function's internal behavior on Android is to capture an Android Runtime (ART) method trace. An ART method trace is a tool that records the execution flow of an app, showing exactly which methods are called, their order, and how much time is spent in each, allowing developers to identify performance bottlenecks. For an empty LaunchedEffect { } call, it would look something like this: LaunchedE

## Android Studio Quail 3 Canary 3 now available

DevFeed: [Android Studio Quail 3 Canary 3 now available](<https://devfeed.tech/articles/android-studio-quail-3-canary-3-now-available-26322.md>)

Original publisher: [Read original article](<https://androidstudio.googleblog.com/2026/07/android-studio-quail-3-canary-3-now.html>)

Author: Android Studio Releaser (noreply@blogger.com)

Published: 2026-07-02T15:19:27Z

Content type: release

Language: en

Sources: [Android Studio Release Updates](<https://devfeed.tech/sources/android-studio-release-updates.md>)

Topics: [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [Android Gradle Plugin](<https://devfeed.tech/topics/android-gradle-plugin.md>), [Release notes](<https://devfeed.tech/topics/release-notes.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [r8](<https://devfeed.tech/tags/r8.md>), [release](<https://devfeed.tech/tags/release.md>), [release-notes](<https://devfeed.tech/tags/release-notes.md>)

### AI overview

Android Studio Quail 3 Canary 3 is available in the Canary channel. The release includes general fixes and features for Android Studio and Android Gradle Plugin 9.4.0-alpha03, with additional fixed issues documented in the release information.

### Source excerpt

Android Studio Quail 3 Canary 3 is now available in the Canary channel. If you already have an Android Studio build on the Canary channel, you can get the update by clicking Help > Check for Updates (or Android Studio > Check for Updates on macOS). Otherwise, you can download it here. For information on new features and changes in Android Studio Quail 3, see the Android Studio Preview release notes. For details of bugs fixed in each previous release of Android Studio Quail 3, see closed issues. General fixes and features Below is a list of general fixes in Android Studio Quail 3 Canary 3 and Android Gradle Plugin 9.4.0-alpha03. These are a result of your bug reports, which help us to make Android Studio better. If you encounter a problem, let us know by reporting a bug. You can also vote for an existing issue to indicate that it also affects you. Fixed Issues Database Inspector Issue #528792471 Database Inspector can't edit/delete database rows Shrinker (R8) Issue #146403477 L8 obfucation mapping not included in app mapping.txt

## Obfuscation Deep Dive: Enhancing R8 and ProGuard for Robust Android Code Protection

DevFeed: [Obfuscation Deep Dive: Enhancing R8 and ProGuard for Robust Android Code Protection](<https://devfeed.tech/articles/obfuscation-deep-dive-enhancing-r8-and-proguard-for-robust-android-code-protection-25958.md>)

Original publisher: [Read original article](<https://kirillr.medium.com/proguard-r8-obfuscation-dictionary-b4541a898eb8?source=rss-7a0a233f88a2------2>)

Author: Kirill Rozov

Published: 2025-05-19T07:40:40Z

Content type: tutorial

Language: en

Sources: [Stories by Kirill Rozov on Medium](<https://devfeed.tech/sources/stories-by-kirill-rozov-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [obfuscation](<https://devfeed.tech/topics/obfuscation.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Reverse Engineering](<https://devfeed.tech/topics/reverse-engineering.md>), [Java](<https://devfeed.tech/topics/java.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [configuration](<https://devfeed.tech/topics/configuration.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [java](<https://devfeed.tech/tags/java.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [r8](<https://devfeed.tech/tags/r8.md>), [reverse-engineering](<https://devfeed.tech/tags/reverse-engineering.md>), [security](<https://devfeed.tech/tags/security.md>)

### AI overview

This tutorial explains how R8 and ProGuard obfuscate Android applications and why their default naming dictionaries can make reverse engineering easier. It presents custom dictionary configuration, Java reserved-keyword names, invalid Windows filename names, and per-build randomized dictionaries, while noting compatibility and testing risks.

### Source excerpt

Obfuscation is a crucial aspect of securing Android applications. While tools like R8 and ProGuard are commonly used, their default configurations primarily aim to reduce app size rather than fortify code against reverse engineering. This article delves into advanced obfuscation techniques to make reverse engineering harder. Understanding Obfuscation Obfuscation transforms readable code into a form that's difficult to interpret. For instance, UserManager might become a, and getUser() could be renamed to b(). R8 and ProGuard perform obfuscation alongside code shrinking and optimization. # R8/ProGuard default dictionary a b c ... z These tools use dictionaries to generate new names, typically starting with single letters (a to z) and progressing to combinations like aa, ab, etc. While this approach minimizes file size, it has drawbacks: Predictable Naming: Limited name variations make it easier to deduce original identifiers. Consistent Builds: Repeated builds produce identical obfuscated names, aiding pattern recognition. Simplified Reverse Engineering: Tools can exploit naming patterns across builds. To counter these issues, customizing the obfuscation dictionary is essential. Implementing Custom Dictionaries R8 and ProGuard allow the use of custom dictionaries via configuration files: # proguard-rules.txt # Add to R8/ProGuard config file -obfuscationdictionary obfuscation-dictionary.tx -classobfuscationdictionary class-dictionary.txt -packageobfuscationdictionary package-dictionary.txt By providing unique dictionaries, you can generate diverse and unpredictable obfuscated names. Advanced Dictionary StrategiesJava Reserved Keywords Using Java's reserved keywords (e.g., if, for, class) as obfuscated names can confuse decompilers, as these are invalid identifiers in source code but acceptable in bytecode. # Java Reserved Keywords dictionary do if for int new ... instanceof synchronized Example of deobfucated Java code with java reserved keywords dictionary package cla

## The curious case of a weird VerifyError crash

DevFeed: [The curious case of a weird VerifyError crash](<https://devfeed.tech/articles/the-curious-case-of-a-weird-verifyerror-crash-25583.md>)

Original publisher: [Read original article](<https://www.marcogomiero.com/posts/2025/bug-hunting-story/>)

Author: Marco Gomiero

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

Content type: article

Language: en

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

Topics: [Android](<https://devfeed.tech/topics/android.md>), [debugging](<https://devfeed.tech/topics/debugging.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [crash](<https://devfeed.tech/tags/crash.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [dependency](<https://devfeed.tech/tags/dependency.md>), [issue](<https://devfeed.tech/tags/issue.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

A journal-style debugging account of a VerifyError runtime crash in FeedFlow's Android release build after upgrading the Android Gradle Plugin to version 8.7. The investigation tests R8, Compose, Kotlin, and dependency combinations, then narrows the problem to code in the dependency graph involving date-string parsing.

### Source excerpt

This post can be considered as a journal entry. I had to clear my thoughts and vent off through writing after spending time debugging this issue. Maybe it will be helpful for future references or an example of the process to follow in such cases. The other day I was doing the usual dependency update routine of FeedFlow when I discovered a runtime crash that happened in the release version (so with R8 enabled) after updating the Android Gradle Plugin (AGP, in the rest of the article) to version 8.7.

## Optimizing Rectangle-Overlap Tests by Removing Conditional Branches

DevFeed: [Optimizing Rectangle-Overlap Tests by Removing Conditional Branches](<https://devfeed.tech/articles/down-a-rabbit-hole-25596.md>)

Original publisher: [Read original article](<https://www.romainguy.dev/posts/2024/down-a-rabbit-hole/>)

Author: Romain Guy

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

Content type: tutorial

Language: en

Sources: [Posts on Romain Guy](<https://devfeed.tech/sources/posts-on-romain-guy.md>)

Topics: [Optimization](<https://devfeed.tech/topics/optimization.md>), [Code](<https://devfeed.tech/topics/code.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Benchmark](<https://devfeed.tech/topics/benchmark.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [assembly](<https://devfeed.tech/tags/assembly.md>), [benchmark](<https://devfeed.tech/tags/benchmark.md>), [code](<https://devfeed.tech/tags/code.md>), [developer](<https://devfeed.tech/tags/developer.md>), [graphics](<https://devfeed.tech/tags/graphics.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [performance](<https://devfeed.tech/tags/performance.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

This article examines optimizing rectangle-overlap tests in Kotlin. It compares generated assembly, replaces logical operators with bitwise operators to remove conditional branches, and reports a 1.7x speedup in a benchmark on a Google Pixel 6.

### Source excerpt

I recently discussed an optimization that I worked on following Leland's successful nerd snipe. That, however, was not the end of it. He also needed to test for intersecting/overlapping rectangles. The most obvious way to achieve this is pretty straightforward: 1// A rectangle is defined by its left (l), top (t), 2// right (r), and bottom (b) coordinates 3data class Rect(val l: Int, val t: Int, val r: Int, val b: Int) { 4 fun overlaps(other: Rect) = 5 l < other.r && other.l < r && t < other.b && other.t < b 6} The source code is nice and tidy, but the generated assembly is less than ideal (as always, the code was optimized with R8 first):

## Crafting Android bytecode analysis tooling using a secret ingredient (Part 1)

DevFeed: [Crafting Android bytecode analysis tooling using a secret ingredient (Part 1)](<https://devfeed.tech/articles/crafting-android-bytecode-analysis-tooling-using-a-secret-ingredient-part-1-22597.md>)

Original publisher: [Read original article](<https://medium.com/bumble-tech/crafting-android-bytecode-analysis-tooling-using-a-secret-ingredient-part-1-13e2d5a65113?source=rss----6353b5325b1a---4>)

Author: Konstantin Zolotov

Published: 2024-02-09T11:50:19Z

Content type: tutorial

Language: en

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

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Tooling](<https://devfeed.tech/topics/tooling.md>), [APK](<https://devfeed.tech/topics/apk.md>), [obfuscation](<https://devfeed.tech/topics/obfuscation.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Java](<https://devfeed.tech/topics/java.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>)

Tags: [andriod-app-development](<https://devfeed.tech/tags/andriod-app-development.md>), [android](<https://devfeed.tech/tags/android.md>), [apk](<https://devfeed.tech/tags/apk.md>), [bytecode](<https://devfeed.tech/tags/bytecode.md>), [compilation](<https://devfeed.tech/tags/compilation.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [dagger](<https://devfeed.tech/tags/dagger.md>), [inlining](<https://devfeed.tech/tags/inlining.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>), [tooling](<https://devfeed.tech/tags/tooling.md>)

### AI overview

This tutorial introduces Android bytecode analysis through DEX inspection and a tool for examining how source-code changes affect compiled binaries. It explains the Android compilation pipeline from Java or Kotlin source through JVM class files and D8-generated DEX files, then describes R8 obfuscation and optimization, including source maps, tree-shaking, inlining, and outlining.

### Source excerpt

During the development process, we often focus on the source code but rarely inspect the compiled bytecode. This means we're missing out on a valuable source of information and data for analysis. How? Let's delve into Dex file inspection and build a tool that demonstrates how source code changes impact the compiled binary. Have you ever set R8 rules to obfuscate your app? Have you used an APK analyzer or a diffuse tool to understand how the code is compiled? Are you confident that debug code hasn't leaked into production? There's another potential pitfall: libraries may provide obfuscation rules (e.g., Gson) that merge with the ones in your project. This means third-party dependencies can alter configurations for the entire app. We often assume everything is fine and that we'll notice if something isn't right. But will we? Does this make you feel uneasy? Does it concern you? Because it certainly concerns me. Here, we'll attempt to enhance the situation and enable you to see precisely how your code changes impact the compiled binary. To better comprehend this, let's start with the code compilation process: It all begins with the Java and/or Kotlin source code, which is then compiled into JVM .class files. Note that at this stage, Java and Kotlin compilers can execute annotation processing tools (APT/KAPT) to generate source code (e.g., Dagger), and Kotlin compiler can run plugins to modify the internal code representation. Then, the D8 compiler takes these compiled classes, third-party libraries (JARs, AARs), and converts them into .dex files. However, if obfuscation and/or minification are enabled (which is almost always the case for release builds), R8 comes into play after D8. R8 obfuscates and optimises the bytecode, and additionally, R8 produces a source map file -- a special file listing all the changes and replacements. Obfuscation replaces human-readable names of various entities (classes, functions, fields, etc.) with very short, yet still unique names, for e

## Comparing Jetpack Compose performance with XML

DevFeed: [Comparing Jetpack Compose performance with XML](<https://devfeed.tech/articles/comparing-jetpack-compose-performance-with-xml-37398.md>)

Original publisher: [Read original article](<https://medium.com/okcredit/comparing-jetpack-compose-performance-with-xml-9462a1282c6b?source=rss----40ea5327aac7---4>)

Author: Pratham Arora

Published: 2022-08-09T05:41:24Z

Content type: article

Language: en

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

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [XML](<https://devfeed.tech/topics/xml.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>), [compose](<https://devfeed.tech/tags/compose.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [mobile-app-development](<https://devfeed.tech/tags/mobile-app-development.md>), [performance](<https://devfeed.tech/tags/performance.md>), [r8](<https://devfeed.tech/tags/r8.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

An Android team compares Jetpack Compose and XML-based layouts in production using frozen-frame rate, slow-frame rate, and median page-load duration. The article also examines Android Runtime AOT compilation as context for the measured results.

### Source excerpt

As Jetpack compose is progressing towards stability, our team decided to measure the performance differences between Compose and XML-based layouts to build the foundation for gradually moving towards Jetpack compose. The differences were measured in terms of frozen frames, slow frames and page load duration. Additionally, we deep-dived into how Android Runtime (ART) optimises the performance by using Ahead-of-time (AOT) compilation. Both the below-mentioned experiments were performed on Production build with R8 enabled. Compose version used throughout was 1.1.0 Let's get started... Experiment -- 1 To begin with, we decided to convert one of the existing screens from XML to compose. Then, using our internal A/B experimentation platform, we made 2 equal cohorts/groups of users. The first cohort would experience the old XML-based screen whereas the other cohort would experience the newly compose built screen. Aim -- To understand the rendering performance of both the screens by comparing frozen frame rate, slow frame rate and page load duration. Screen -- This screen shows all the transactions as well as their summary in an interval. Results - Frozen frame percentage: For compose-based layout, the frozen frame rate came out to be 0.044% whereas it was 0.034% for XML-based layout. An alternate way to understand this can be, that if we open this XML-based activity, then nearly 3.4 frames out of 10,000 frames would fall under the frozen frame category. Similarly, for the compose-based activity, it would be 4.3 frames out of 10,000 frames. Slow frame percentage: For compose-based layout, the slow frame rate came out to be 8.91% whereas it was 9.93% for XML-based layout. Like frozen frames, ~10 out of 100 frames would fall under the slow frame category for XML-based layout. Whereas it was ~9 out of 100 frames for compose-based activity. Median Page Load Duration (in milliseconds): Internally, we define page load duration as the time taken from launching an activity to drawing it

## Влияние Kotlin data-классов на вес приложения

DevFeed: [Влияние Kotlin data-классов на вес приложения](<https://devfeed.tech/articles/kotlin-data-23635.md>)

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

Author: ChPr (Badoo)

Published: 2021-03-04T14:13:38Z

Content type: article

Language: ru

Sources: [Badoo EN](<https://devfeed.tech/sources/badoo-en.md>), [Badoo RU](<https://devfeed.tech/sources/badoo-ru.md>)

Topics: [data](<https://devfeed.tech/topics/data.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [R8](<https://devfeed.tech/topics/r8.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [data](<https://devfeed.tech/tags/data.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-compiler](<https://devfeed.tech/tags/kotlin-compiler.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

A Kotlin developer investigates the cost of using many data classes in an application. The article describes an experiment involving replacing data classes with ordinary classes and discusses how release optimizers such as R8 affect their generated methods.

### Source excerpt

Kotlin имеет много классных особенностей: null safety, smart casts, интерполяция строк и другие. Но одной из самых любимых разработчиками, по моим наблюдениям, являются data-классы. Настолько любимой, что их часто используют даже там, где никакой функциональности data-класса не требуется. В этой статье я с помощью эксперимента постараюсь понять, какова реальная цена использования большого количества data-классов в приложении. Я попробую удалить все data-классы, не сломав компиляцию, но сломав приложение, а потом расскажу о результатах и выводах этого эксперимента. Читать дальше ->

## Wildcard ProGuard/R8 Rule Can Remove Android Synchronization Calls

DevFeed: [Wildcard ProGuard/R8 Rule Can Remove Android Synchronization Calls](<https://devfeed.tech/articles/how-to-break-your-android-app-with-proguard-r8-24744.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/how-to-break-your-android-app-with-proguard-r8-6566bc387b63?source=rss----65bd178b00af---4>)

Author: Paul Woitaschek

Published: 2021-03-02T15:19:22Z

Content type: tutorial

Language: en

Sources: [YAZIO Engineering - Medium](<https://devfeed.tech/sources/yazio-engineering-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Android Gradle Plugin](<https://devfeed.tech/topics/android-gradle-plugin.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [instrumentation](<https://devfeed.tech/tags/instrumentation.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [r8](<https://devfeed.tech/tags/r8.md>), [testing](<https://devfeed.tech/tags/testing.md>)

### AI overview

An Android debugging article explains how instrumentation tests and a network call began hanging after an Android Gradle Plugin update. The cause was a ProGuard/R8 `-assumenosideeffects` rule using a wildcard for `android.util.Log`, which also matched superclass methods including synchronization methods on `Object`.

### Source excerpt

I recently updated the android gradle plugin to 4.0.0. While developing, everything went smoothly and at some point I was ready to cut a release. The very last manual testing of the release app bundle was also fine so no Proguard / R8 issues on the first sight either. Then I thought: Let me check the CI results again. Everything was fine, but: The instrumentation tests. Almost all of them were timing out. After inspecting the logs, they all hang at the end of the on-boarding. Strangely the loading spinner was loading for way longer than the timeout should be. So I tested it on my phone and faced the same results. At that time I had no idea it was caused by updating AGP, so I did a 2 hours long git bisect. Okay, now lets create a minimal self reproducible bug report because I found a huge bug in AGP, everyone should know about immediately. I created a Hello World project that was making a single network call and printed it results into a TextView. Strangely here it did not reproduce. After experimenting with the OkHttp configuration and testing if it was related to some gradle plugin, I finally had the idea that it might be related to R8. So I added my proguard configuration and now the network call hang! Let's locate the issue further. I was step by step removing lines from my proguard configuration until only a single line was left: -assumenosideeffects class android.util.Log { public * ; } Now what is this? How is that even slightly related to anything? It should remove the log spam of some third party libraries we're using. So I was asking Mads Ager. (he works on D8/R8) you have to be very careful with -assumenosideeffects The problem is that in order for -assumenosideeffects to have the effect of actually removing calls, it matches up the class hierarchy. Therefore, this rule says that anything public in android.util.Log and its superclasses has no side-effects. That include the synchronization methods defined on Object. So, please don't use * wildcards in conne

## Analyze Stack Traces in Android Studio

DevFeed: [Analyze Stack Traces in Android Studio](<https://devfeed.tech/articles/analyze-stack-traces-in-android-studio-25825.md>)

Original publisher: [Read original article](<https://segunfamisa.com/posts/analyze-stack-trace-in-android-studio>)

Author: Segun Famisa

Published: 2020-06-22T09:00:00Z

Content type: tutorial

Language: en

Sources: [Segun Famisa](<https://devfeed.tech/sources/segun-famisa.md>)

Topics: [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [debugging](<https://devfeed.tech/topics/debugging.md>), [Development](<https://devfeed.tech/topics/development.md>), [Firebase](<https://devfeed.tech/topics/firebase.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [debug](<https://devfeed.tech/tags/debug.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [firebase](<https://devfeed.tech/tags/firebase.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

A tutorial on using Android Studio's built-in stack trace analysis tool to format imported crash reports and make their entries clickable and navigable. It also discusses obfuscated stack traces from release builds using ProGuard or R8/D8.

### Source excerpt

Introduction As programmers, we spend a significant part of our time debugging errors. Stack traces are very useful in doing so, and careful analysis of the stack traces help us to locate and fix the problem. In this post, I'll show a quick way we can use Android Studio to make it easier to debug errors using the built-in "stack trace analysis" tool. Context As Android developers, once an app is released into the wild (i.e deployed on a device outside our development environment), we have to rely on crash reporting tools like Firebase Crash reporting, Instabug, Appsee, etc, to collect these reports and aggregate them for us. The experience of working with stack traces varies from whether we are in development or in production. In development, we often get the stack traces right there in the logcat of Android Studio where each line in the stack trace is a clickable link that takes us straight to corresponding line of code. On the other hand, when we collect crash reports and stack traces in the wild, we collect them as text - sometimes formatted, sometimes not. This adds the additional overhead of having to format the stack trace in order to be human-readable and then manually search for the corresponding lines of code in the IDE. Using the "Anaylze Stack Trace" tool Luckily for us, Android Studio solves a part of this problem and makes it easier for us when we are analyzing stack traces that are generated in the wild. When you receive a stack trace, you can import them into Android Studio and introduce all the nice formatting, hyperlink and navigating functionality that we get as if it's a crash from the logcat. The Android Developer docs page pretty much explains how to use this tool, but I'll summarize the steps here: In the Android Studio menu bar, navigate to "Analyze > Analyze Stack Trace or Thread Dump" Paste the stack trace in the window Click "Normalize" to format the stack trace - in case it is not already formatted. Click on "OK" to complete this. On click

## How an R8 ProGuard rule can break Android application synchronization

DevFeed: [How an R8 ProGuard rule can break Android application synchronization](<https://devfeed.tech/articles/how-to-break-your-android-app-with-proguard-r8-26006.md>)

Original publisher: [Read original article](<https://medium.com/yazio-engineering/how-to-break-your-android-app-with-proguard-r8-6566bc387b63?source=rss-fbf9b6d94e65------2>)

Author: Paul Woitaschek

Published: 2020-06-08T05:52:07Z

Content type: tutorial

Language: en

Sources: [Stories by Paul Woitaschek on Medium](<https://devfeed.tech/sources/stories-by-paul-woitaschek-on-medium.md>)

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Android Gradle Plugin](<https://devfeed.tech/topics/android-gradle-plugin.md>), [Android](<https://devfeed.tech/topics/android.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [bug](<https://devfeed.tech/tags/bug.md>), [ci](<https://devfeed.tech/tags/ci.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [r8](<https://devfeed.tech/tags/r8.md>), [synchronization](<https://devfeed.tech/tags/synchronization.md>), [testing](<https://devfeed.tech/tags/testing.md>)

### AI overview

The article investigates Android instrumentation tests and network calls hanging after an Android Gradle Plugin update. It traces the behavior to the R8 rule `-assumenosideeffects class android.util.Log { public * ; }`, which can treat synchronization methods inherited from `Object` as having no side effects. The author recommends avoiding wildcards with `-assumenosideeffects` and specifying exact signatures.

### Source excerpt

I recently updated the android gradle plugin to 4.0.0. While developing, everything went smoothly and at some point I was ready to cut a release. The very last manual testing of the release app bundle was also fine so no Proguard / R8 issues on the first sight either. Then I thought: Let me check the CI results again. Everything was fine, but: The instrumentation tests. Almost all of them were timing out. After inspecting the logs, they all hang at the end of the on-boarding. Strangely the loading spinner was loading for way longer than the timeout should be. So I tested it on my phone and faced the same results. At that time I had no idea it was caused by updating AGP, so I did a 2 hours long git bisect. Okay, now lets create a minimal self reproducible bug report because I found a huge bug in AGP, everyone should know about immediately. I created a Hello World project that was making a single network call and printed it results into a TextView. Strangely here it did not reproduce. After experimenting with the OkHttp configuration and testing if it was related to some gradle plugin, I finally had the idea that it might be related to R8. So I added my proguard configuration and now the network call hang! Let's locate the issue further. I was step by step removing lines from my proguard configuration until only a single line was left: -assumenosideeffects class android.util.Log { public * ; } Now what is this? How is that even slightly related to anything? It should remove the log spam of some third party libraries we're using. So I was asking Mads Ager. (he works on D8/R8) you have to be very careful with -assumenosideeffects The problem is that in order for -assumenosideeffects to have the effect of actually removing calls, it matches up the class hierarchy. Therefore, this rule says that anything public in android.util.Log and its superclasses has no side-effects. That include the synchronization methods defined on Object. So, please don't use * wildcards in conne

## R8 Optimization: Lambda Groups

DevFeed: [R8 Optimization: Lambda Groups](<https://devfeed.tech/articles/r8-optimization-lambda-groups-20959.md>)

Original publisher: [Read original article](<https://jakewharton.com/r8-optimization-lambda-groups/>)

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

Content type: article

Language: en

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

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [apk](<https://devfeed.tech/tags/apk.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lambda](<https://devfeed.tech/tags/lambda.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

An analysis of how R8 optimizes Kotlin lambda groups in Android applications, using compiled examples to compare the generated classes before and after optimization.

### 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". Lambda usage in Kotlin feels more pervasive than Java because of the functional nature of the Kotlin standard library. Some lambdas are merely syntactic constructs that are eliminated at compile-time through the use of inline functions. The rest materialize into whole classes for use at runtime. The mechanisms by which lambdas work was covered in the Android Java 8 support post, but here's a quick refresher: javac hoists lambda bodies to a package-private method and writes an invoke-dynamic bytecode for the target lambda type at the call-site. The JVM spins a class at runtime of the desired type and invokes the package-private method in the method body. Android does not ship this runtime support, so D8 performs a compile-time transformation to a class which implements the desired type and which invokes the package-private method. kotlinc skips the invoke-dynamic bytecode (even when targeting Java 8+) and generates full classes directly. Here's two Kotlin classes and some lambda usage that we can experiment with. class Employee( val id: String, val joined: LocalDate, val managerId: String? ) class EmployeeRepository(val allEmployees: () -> Sequence<Employee>) { fun joinedAfter(date: LocalDate) = allEmployees() .filter { it.joined >= date } .toList() fun reports(manager: Employee) = allEmployees() .filter { it.managerId == manager.id } .toList() } The EmployeeRepository class accepts a lambda which produces a sequence of employees and exposes two functions for listing the employees who joined after a particular date and those who report to a particular employee. Both functions use a lambda to filter the sequence to the desired items before converting to a list. Kotlin's approach to lambdas is immediately visible after compiling this class. $ kotlinc EmployeeRepos

## Which is better on Android: divide by 2 or shift by 1?

DevFeed: [Which is better on Android: divide by 2 or shift by 1?](<https://devfeed.tech/articles/which-is-better-on-android-divide-by-2-or-shift-by-1-20983.md>)

Original publisher: [Read original article](<https://jakewharton.com/which-is-better-on-android-divide-by-two-or-shift-by-one/>)

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

Content type: tutorial

Language: en

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

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Java](<https://devfeed.tech/topics/java.md>), [R8](<https://devfeed.tech/topics/r8.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>), [writing](<https://devfeed.tech/tags/writing.md>)

### AI overview

This article investigates whether dividing by 2 or shifting by 1 is better on Android. It examines how Java and Kotlin source code is transformed by javac or kotlinc, D8/R8, and ART, using bytecode and Dalvik bytecode examples. The discussion is motivated by work porting the AndroidX collection library to Kotlin Multiplatform and by concerns about performance, readability, and compiler optimization.

### Source excerpt

I've been porting the AndroidX collection library to Kotlin multiplatform to experiment with binary compatibility, performance, tooling, and the different memory models. Some of the data structures in the library use array-based binary trees to store elements. The Java code has a lot of shifts to replace power-of-two multiplications and divides. When ported to Kotlin, these turn into the slightly-awkward infix operators which further obfuscate the intent of the code. I sampled a few people about bitwise shifts vs. multiplication/division and many had heard anecdotal claims of shifts having better performance, but everyone remained skeptical of whether it was true. Some assumed that one of the compilers seen before the code ran on a CPU would handle optimizing this case. In an effort to satisfy my curiosity (and partially to avoid Kotlin's infix bitwise operators) I set out to answer which is better and some other related questions. Let's go! Does anyone optimize this? There are three major compilers that code passes through before it hits the CPU: javac/kotlinc, D8/R8, and ART. Each of these has the opportunity to optimize. But do they? javac class Example { static int multiply(int value) { return value * 2; } static int divide(int value) { return value / 2; } static int shiftLeft(int value) { return value << 1; } static int shiftRight(int value) { return value >> 1; } } This Java can be compiled with javac from JDK 14 and the resulting bytecode can be displayed with javap. $ javac Example.java $ javap -c Example Compiled from "Example.java" class Example { static int multiply(int); Code: 0: iload_0 1: iconst_2 2: imul 3: ireturn static int divide(int); Code: 0: iload_0 1: iconst_2 2: idiv 3: ireturn static int shiftLeft(int); Code: 0: iload_0 1: iconst_1 2: ishl 3: ireturn static int shiftRight(int); Code: 0: iload_0 1: iconst_1 2: ishr 3: ireturn } Every method starts with iload_0 which loads the first argument value. The multiply and divide methods both then have

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

## Diving deep into Android Dex bytecode

DevFeed: [Diving deep into Android Dex bytecode](<https://devfeed.tech/articles/diving-deep-into-android-dex-bytecode-38625.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_02_02_diving_deep_into_android_dex_bytecode/>)

Published: 2020-02-02T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Java](<https://devfeed.tech/topics/java.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [bytecode](<https://devfeed.tech/tags/bytecode.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [inlining](<https://devfeed.tech/tags/inlining.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [memory](<https://devfeed.tech/tags/memory.md>), [performance](<https://devfeed.tech/tags/performance.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

This practical guide explains how Kotlin and Java code is transformed into Android DEX bytecode. It describes examining Java bytecode, the role of the Dalvik bytecode format and Android Runtime, and the compilation tools kotlinc, javac, d8, and R8, with attention to possible memory and performance effects.

### Source excerpt

Source Introduction Modern Android development is based on Kotlin, which is interoperable with Java. Whenever we use some cool feature from Kotlin (say High-order functions) under the hood (when running on JVM) the feature is implemented in terms of Java bytecode. This might lead to some overheads in memory and performance if used without caution (for example excessive usage of lambdas with parameters without inlining might produce a lot of anonymous classes and put additional pressure on GC).

## Fixing the Initial Dispatchers.Main Delay in Kotlin Coroutines

DevFeed: [Fixing the Initial Dispatchers.Main Delay in Kotlin Coroutines](<https://devfeed.tech/articles/a-dispatcher-of-many-threads-37550.md>)

Original publisher: [Read original article](<https://colintheshots.com/writing/a-dispatcher-of-many-threads-part-1-2/>)

Published: 2019-12-19T03:02:18Z

Content type: tutorial

Language: en

Sources: [Colin The Shots](<https://devfeed.tech/sources/colin-the-shots.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>), [R8](<https://devfeed.tech/topics/r8.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [builds](<https://devfeed.tech/tags/builds.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>)

### AI overview

This article explains an initial delay of up to a quarter second when Android apps first use Kotlin Coroutines' Dispatchers.Main. It attributes the delay to ServiceLoader triggering a checksum of the entire JAR inside the APK and describes a stable fix using Kotlin coroutines 1.3.3 or higher, required Proguard rules, and R8 optimization.

### Source excerpt

Kotlin Coroutines have been almost unanimously received with applause by the Android software development community. However, there are some significant issues I have noticed in practice that are

## ProGuard & R8: Part 2

DevFeed: [ProGuard & R8: Part 2](<https://devfeed.tech/articles/proguard-r8-part-2-32346.md>)

Original publisher: [Read original article](<https://dustn.dev/post/2019-11-20-android-build-pipeline-hands-on/>)

Author: dustin@dustn.dev (Dustin Summers)

Published: 2019-11-20T09:00:00Z

Content type: tutorial

Language: en

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

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Android](<https://devfeed.tech/topics/android.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [Java](<https://devfeed.tech/topics/java.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [code](<https://devfeed.tech/tags/code.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [proguard-android-r8-smali-dalvik-jvm-kotlin-art-gradle-java](<https://devfeed.tech/tags/proguard-android-r8-smali-dalvik-jvm-kotlin-art-gradle-java.md>), [r8](<https://devfeed.tech/tags/r8.md>), [sdk](<https://devfeed.tech/tags/sdk.md>), [terminal](<https://devfeed.tech/tags/terminal.md>)

### AI overview

A hands-on tutorial covering the Android build pipeline with ProGuard and R8. It walks through compiling Java or Kotlin source code, using Android Build Tools, and examining generated bytecode.

### Source excerpt

This blog post is the second in a series to teach about the build tools ProGuard and R8, and the first in the hands-on portion of the series. In the first post I talked about the Android Build Pipeline. In this blog, I would like to actually reinforce those concepts with hands on exercises. If you haven't read the first blog on this topic, this is part two in that series, so I highly suggest going back and understanding that material first.

## Understanding the Android Build Pipeline with ProGuard and R8

DevFeed: [Understanding the Android Build Pipeline with ProGuard and R8](<https://devfeed.tech/articles/proguard-r8-part-1-32347.md>)

Original publisher: [Read original article](<https://dustn.dev/post/2019-11-6-understanding-the-android-build-pipeline/>)

Author: dustin@dustn.dev (Dustin Summers)

Published: 2019-11-06T12:08:40Z

Content type: tutorial

Language: en

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

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Code](<https://devfeed.tech/topics/code.md>), [obfuscation](<https://devfeed.tech/topics/obfuscation.md>), [software-development](<https://devfeed.tech/topics/software-development.md>), [Software](<https://devfeed.tech/topics/software.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compilation](<https://devfeed.tech/tags/compilation.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>), [proguard](<https://devfeed.tech/tags/proguard.md>), [proguard-android-r8-smali-dalvik-jvm-kotlin-art-gradle-java](<https://devfeed.tech/tags/proguard-android-r8-smali-dalvik-jvm-kotlin-art-gradle-java.md>), [r8](<https://devfeed.tech/tags/r8.md>), [software-development](<https://devfeed.tech/tags/software-development.md>), [tutorials](<https://devfeed.tech/tags/tutorials.md>)

### AI overview

A tutorial explaining the Android build pipeline and where ProGuard and R8 fit into it. It introduces compilation stages, optimization, shrinking, and code obfuscation, with an emphasis on understanding and diagnosing how these tools transform source code into bytecode.

### Source excerpt

Tools such as R8 and ProGuard are available for free, but to many they are a black box that code goes into and stuff comes out. My goal is to demystify the black box and teach developers how to properly diagnose the code going into and coming out of these build tools. It will also explain why you should care and why applying these tools should be a priority before shipping any code into the wild.

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