It’s a non-transitive R class world

After Duplo modularization, we noticed that the task producing a transitive R class was taking a significant amount of time to execute. To eliminate this task altogether, and since the non-transitive R class is advertised to have up to 40% incremental build time improvement, we decided to migrate our codebase to use it. If you’re not…

Saif Chaouachi
7 min readintermediate
--
View Original

Overview

The article discusses the migration to a non-transitive R class in Android development, detailing the process, benefits, and challenges faced by the Slack engineering team. It highlights the improvements in build times and APK size, along with the conventions established for resource referencing.

What You'll Learn

1

How to migrate to non-transitive R class in an Android project

2

Why non-transitive R class improves build times and APK size

3

How to establish conventions for resource referencing in Kotlin and Java

Prerequisites & Requirements

  • Understanding of Android development and Gradle
  • Familiarity with Android Studio

Key Questions Answered

What is the non-transitive R class in Android development?
The non-transitive R class is a feature in the Android Gradle Plugin that allows each module's R class to only include resources declared in that module, improving build performance by eliminating unnecessary dependencies. This feature is enabled by default for new projects since Android Studio Bumblebee.
What benefits were observed after migrating to non-transitive R class?
After migrating to the non-transitive R class, Slack experienced a ~14% improvement in incremental build times following resource changes and an ~8.5% reduction in APK/DEX size, which amounted to approximately 5.5MB of code. These improvements enhanced overall development efficiency.
How did Slack enforce conventions for resource referencing?
Slack enforced conventions by using import aliases in Kotlin for referencing resources and established lint checks to ensure that only local module R classes could be imported without aliases. This helped maintain consistency and clarity in the codebase.
What challenges did Slack face during the migration process?
During the migration, Slack encountered performance issues with Android Studio when trying to refactor R references across a large codebase of over 400 modules. This led them to pivot their strategy to a more manual approach for updating resource references.

Key Statistics & Figures

Incremental build time improvement
~14%
Observed after migrating to non-transitive R class following resource or layout changes.
Reduction in APK/DEX size
~8.5%
This reduction translates to approximately 5.5MB of code, enhancing app performance.

Technologies & Tools

Some links below are affiliate links. We may earn a commission if you make a purchase.

Key Actionable Insights

1
Implement import aliases for resource referencing in Kotlin to simplify code and improve readability.
Using import aliases can reduce verbosity and make it easier for developers to reference resources without needing to use fully-qualified names, enhancing code maintainability.
2
Utilize lint checks to enforce coding conventions related to resource imports.
By implementing lint checks, teams can automatically identify and correct deviations from established conventions, ensuring consistency across the codebase and reducing potential errors.
3
Monitor build performance metrics after migrating to non-transitive R class to quantify improvements.
Tracking build times and APK sizes post-migration can help teams assess the effectiveness of their transition and identify further optimization opportunities.

Common Pitfalls

1
Failing to establish clear conventions for resource referencing can lead to confusion and inconsistencies in the codebase.
Without defined conventions, developers may use different styles for referencing resources, making the code harder to read and maintain. Establishing and enforcing guidelines helps mitigate this risk.
2
Over-reliance on automated tools for migration can cause performance issues, especially in large codebases.
Automated refactoring tools may struggle with extensive codebases, leading to slow performance or unresponsive IDEs. A more manual approach may be necessary to ensure a smooth migration.

Related Concepts

Android Development
Gradle Build System
Resource Management In Multi-module Projects