mapbox / mapbox/mapbox-maps-android

[R8] Maps and Search SDK consumer rules apply app-wide and significantly restrict optimization

Open
#2,731 0 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged bug :beetle:
Dominant language
Kotlin
Stars
578
Forks
161
PR merge metrics
No merged PRs in 30d

Description

## Description

The consumer ProGuard rules bundled with the Mapbox Maps and Search SDKs contain several app-wide and package-wide rules that significantly restrict R8 shrinking, optimization, and obfuscation outside Mapbox code.

We found this using AGP’s R8 configuration analyzer.

## Versions

- `com.mapbox.maps:android-ndk27:11.16.4`
- `com.mapbox.common:common-ndk27:24.16.4`
- `com.mapbox.search:mapbox-search-android-ndk27:2.15.0`
- `com.mapbox.search:base-ndk27:2.15.0`
- Android Gradle Plugin: `9.3.1`
- R8 full mode
- `proguard-android-optimize.txt`
- Minification and resource shrinking enabled

## Highest-impact rules

### Global enum rule

`com.mapbox.search:base-ndk27:2.15.0` bundles:

```proguard
-keepclassmembers enum * {
;
}
```

Because this targets `enum *`, it affects enums throughout the entire application and all dependencies—not only Mapbox enums.

In our application it matches 10,916 fields and prevents shrinking, optimization, and obfuscation for them.

Could this be scoped to Mapbox Search enum types that require name preservation?

### Entire Maps SDK package

```proguard
-keep class !com.mapbox.maps.extension.**,!com.mapbox.maps.plugin.**,com.mapbox.maps.** {
*;
}
```

This matches:

- 748 classes
- 3,725 fields
- 4,815 methods
- 9,288 items total

Could this rule be narrowed to classes and members accessed through JNI, reflection, or serialization?

### Entire Mapbox Common package

```proguard
-keep class com.mapbox.common.** {
*;
}
```

This matches:

- 711 classes
- 1,405 fields
- 3,322 methods
- 5,438 items total

Could this be replaced with surgical rules for JNI-bound or reflectively accessed types?

### Entire Gson library

`com.mapbox.maps:android-ndk27:11.16.4` bundles:

```proguard
-keep class com.google.gson.** {
*;
}
```

This keeps the complete Gson implementation, including code unrelated to Mapbox.

In our application it matches:

- 221 classes
- 469 fields
- 1,244 methods
- 1,934 items total

Modern Gson versions bundle their own consumer rules. Could this blanket rule be removed and replaced with rules targeting only Mapbox models that require Gson reflection?

### Search bindgen package

```proguard
-keep class com.mapbox.search.internal.bindgen.** {
*;
}
```

This matches:

- 114 classes
- 636 fields
- 820 methods
- 1,570 items total

If these classes are JNI-bound, could the rule permit optimization or shrinking where native lookup does not depend on the affected symbol?

## Redundant rules

### SerializedName fields

Mapbox Search bundles:

```proguard
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName ;
}
```

This matches 703 fields. The analyzer reports it as subsumed by Gson’s bundled conditional rule:

```proguard
-if class *
-keepclasseswithmembers,allowobfuscation class <1> {
@com.google.gson.annotations.SerializedName ;
}
```

Could the Mapbox copy be removed in favour of Gson’s consumer configuration?

### Unused legacy package rules

The following rules match no items in our application:

```proguard
-keep class com.mapbox.mapboxsdk.log.** {
*;
}

-keep class com.mapbox.mapboxsdk.text.** {
*;
}
```

Could these legacy rules be removed from the current Maps SDK consumer configuration?

## Aggregate impact

Accounting for overlap with rules from other dependencies, Mapbox-originating rules uniquely restrict approximately:

- 25,010 items from optimization
- 17,046 items from shrinking
- 15,901 items from obfuscation

These are R8 pre-optimization item counts, not APK byte-size measurements, and some rules are clearly required for correct JNI or reflection behaviour. They indicate the available optimization headroom if the consumer rules can be made more surgical.

## Requested improvement

Would you consider reviewing the bundled consumer rules to:

1. Scope wildcard rules to Mapbox-owned packages.
2. Preserve only types and members accessed through JNI, reflection, or serialization.
3. Apply `allowoptimization`, `allowshrinking`, or `allowobfuscation` where safe.
4. Remove the blanket Gson keep rule and rely on Gson’s bundled configuration.
5. Remove rules subsumed by dependency-provided consumer rules.
6. Remove unused rules for legacy Mapbox packages.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the consumer ProGuard rules bundled by the Maps, Common, and Search SDK artifacts, then reproduce the findings with AGP’s R8 configuration analyzer. Review the global enum, package-wide, Gson, bindgen, redundant SerializedName, and legacy-package rules. Done means narrowing or removing rules where safe while preserving JNI, reflection, and serialization behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
build-system, devtools, performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.