DO NOT SUBMIT Add an R8-optimized example app This change adds a new example project under examples/r8-optimized to demonstrate building an Android application with R8 optimization and resource shrinking enabled. The example includes both android_binary and android_application targets, along with their corresponding ProGuard configuration files. PiperOrigin-RevId: 967426373 Change-Id: I1f2369c157adc91f3b6a391d2e9164febadf376a
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 0e06c8e..19e597d 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml
@@ -18,6 +18,25 @@ rules_flags: &rules_flags ? "--enable_bzlmod=false" ? "--enable_workspace=true" +bzlmod_flags: &bzlmod_flags + <<: *rules_flags + ? "--enable_bzlmod" + ? "--enable_workspace=false" + +# These flags are used to build the app using the mobile-install aspect +# Note that this does not actually run an install, just validates +# that at least the build part of MI works. +# Note to users: Do NOT run bazel build with these aspect and output_group +# flags. These are for testing purposes only! +mi_aspect_flags: &mi_aspect_flags + <<: *bzlmod_flags + # Do NOT put these in your bazelrc. Do NOT use these for mobile-install or build/run/test commands. + ? "--aspects=@rules_android//mobile_install:mi.bzl%MIASPECT" + ? "--output_groups=mobile_install_INTERNAL_,mobile_install_launcher_INTERNAL_,-_,-defaults" + # Latest bazel's JavaBuilder is build at java 21. For some reason the MI aspect + bazel build throws + # a classcode version conflict, and not the other tests in this presubmit, so the below flag + # is a crude workaround for that problem. + ? "--tool_java_runtime_version=21" tools: &tools name: "Tools" @@ -110,6 +129,31 @@ ? "--enable_workspace=false" ? "--//rules/flags:manifest_merge_order=legacy" +basicapp: &basicapp + platform: ${{ platform }} + bazel: ${{ bazel }} + working_directory: examples/basicapp + build_flags: + <<: *rules_flags + build_targets: + - "//java/com/basicapp:basic_app" + - "//java/com/basicapp:basic_app_bundle" +basicapp_bzlmod: &basicapp_bzlmod + <<: *basicapp + build_flags: + <<: *bzlmod_flags + +r8_app: &r8_app + <<: *basicapp + working_directory: examples/r8-optimized + build_targets: + - "//:r8_app" + - "//:r8_app_bundle" +r8_app_bzlmod: &r8_app_bzlmod + <<: *r8_app + build_flags: + <<: *bzlmod_flags + tasks: tools: platform: ${{ platform }} @@ -155,69 +199,46 @@ # <<: *rules_coverage basicapp: name: "Basic app" - platform: ${{ platform }} - bazel: ${{ bazel }} - working_directory: examples/basicapp - build_flags: - <<: *rules_flags - build_targets: - - "//java/com/basicapp:basic_app" - - "//java/com/basicapp:basic_app_bundle" + <<: *basicapp basicapp_bzlmod: name: "Basic app bzlmod" - platform: ${{ platform }} - bazel: ${{ bazel }} - working_directory: examples/basicapp - build_flags: - <<: *rules_flags - ? "--enable_bzlmod" - ? "--enable_workspace=false" - build_targets: - - "//java/com/basicapp:basic_app" - - "//java/com/basicapp:basic_app_bundle" + <<: *basicapp_bzlmod windows_basicapp: name: "Basic app windows" platform: "windows" - bazel: ${{ bazel }} - working_directory: examples/basicapp - build_flags: - <<: *rules_flags - build_targets: - - "//java/com/basicapp:basic_app" - - "//java/com/basicapp:basic_app_bundle" + <<: *basicapp windows_basicapp_bzlmod: name: "Basic app windows bzlmod" platform: "windows" - bazel: ${{ bazel }} - working_directory: examples/basicapp - build_flags: - <<: *rules_flags - ? "--enable_bzlmod" - ? "--enable_workspace=false" - build_targets: - - "//java/com/basicapp:basic_app" - - "//java/com/basicapp:basic_app_bundle" + <<: *basicapp_bzlmod basicapp_mi_aspect: # Build the app using the mobile-install aspect - # Note that this does not actually run an install, just validates - # that at least the build part of MI works. - # Note to users: Do NOT run bazel build with these aspect and output_group - # flags. These are for testing purposes only! name: "Basic app mobile-install aspect" - platform: ${{ platform }} - bazel: ${{ bazel }} - working_directory: examples/basicapp + <<: *basicapp build_flags: - <<: *rules_flags - ? "--enable_bzlmod" - ? "--enable_workspace=false" - # Do NOT put these in your bazelrc. Do NOT use these for mobile-install or build/run/test commands. - ? "--aspects=@rules_android//mobile_install:mi.bzl%MIASPECT" - ? "--output_groups=mobile_install_INTERNAL_,mobile_install_launcher_INTERNAL_,-_,-defaults" - # Latest bazel's JavaBuilder is build at java 21. For some reason the MI aspect + bazel build throws - # a classcode version conflict, and not the other tests in this presubmit, so the below flag - # is a crude workaround for that problem. - ? "--tool_java_runtime_version=21" + <<: *mi_aspect_flags build_targets: - "//java/com/basicapp:basic_app" + r8_app: + name: "R8 app" + <<: *r8_app + r8_app_bzlmod: + name: "R8 app bzlmod" + <<: *r8_app_bzlmod + windows_r8_app: + name: "R8 app windows" + platform: "windows" + <<: *r8_app + windows_r8_app_bzlmod: + name: "R8 app windows bzlmod" + platform: "windows" + <<: *r8_app_bzlmod + r8_app_mi_aspect: + # Build the app using the mobile-install aspect + name: "R8 app mobile-install aspect" + <<: *r8_app + build_flags: + <<: *mi_aspect_flags + build_targets: + - "//:r8_app"
diff --git a/examples/r8-optimized/.bazelrc b/examples/r8-optimized/.bazelrc new file mode 100644 index 0000000..08999d7 --- /dev/null +++ b/examples/r8-optimized/.bazelrc
@@ -0,0 +1,37 @@ +# Config for library desugaring +common:core_library_desugaring --desugar_java8_libs + +# Flags to enable mobile-install v3 +mobile-install --mode=skylark --mobile_install_aspect=@rules_android//mobile_install:mi.bzl --mobile_install_supported_rules=android_binary +# Required to build Android builder tools +common --java_language_version=17 +common --java_runtime_version=17 +common --tool_java_language_version=17 +# Required to invoke the Studio deployer jar +common --tool_java_runtime_version=17 + +# Workaround for a rules_java + bazel < 8.3.0 issue. It should only be relevant +# for bazel@HEAD and rolling releases. +# https://github.com/bazelbuild/bazel/pull/26119 +common --repositories_without_autoloads=bazel_features_version,bazel_features_globals,cc_compatibility_proxy + +# Newer versions of protobuf require downstream transitive projects to set C++ language version flags. +common:linux --cxxopt=-std=c++17 +common:linux --host_cxxopt=-std=c++17 +common:macos --cxxopt=-std=c++17 +common:macos --host_cxxopt=-std=c++17 +common:windows --cxxopt=/std:c++17 +common:windows --host_cxxopt=/std:c++17 +# Suppress warnings from external repos +common:linux --per_file_copt=external/.*@-w +common:linux --host_per_file_copt=external/.*@-w +common:macos --per_file_copt=external/.*@-w +common:macos --host_per_file_copt=external/.*@-w +common:windows --per_file_copt=external/.*@/w +common:windows --host_per_file_copt=external/.*@/w + +# Enable protobuf MSVC support on Windows +build:windows --define=protobuf_allow_msvc=true + +common --enable_platform_specific_config +
diff --git a/examples/r8-optimized/.gitignore b/examples/r8-optimized/.gitignore new file mode 100644 index 0000000..63f1fef --- /dev/null +++ b/examples/r8-optimized/.gitignore
@@ -0,0 +1 @@ +*.lock
diff --git a/examples/r8-optimized/BUILD b/examples/r8-optimized/BUILD new file mode 100644 index 0000000..bfc96d7 --- /dev/null +++ b/examples/r8-optimized/BUILD
@@ -0,0 +1,30 @@ +load( + "@rules_android//android:rules.bzl", + "android_application", + "android_binary", +) + +android_binary( + name = "r8_app", + custom_package = "com.r8app", + manifest = "//java/com/r8app:AndroidManifest.xml", + proguard_generate_mapping = True, + proguard_specs = [ + "proguard-android-optimize.txt", + "proguard-rules.pro", + ], + shrink_resources = True, + deps = ["//java/com/r8app:r8_lib"], +) + +android_application( + name = "r8_app_bundle", + # bundle_config_file or feature_modules must be specified to get an aab + bundle_config_file = "//java/com/r8app:bundle_config.pb.json", + manifest = "//java/com/r8app:AndroidManifest.xml", + manifest_values = { + "applicationId": "com.r8app", + "versionCode": "1", + }, + deps = ["//java/com/r8app:r8_lib"], +)
diff --git a/examples/r8-optimized/MODULE.bazel b/examples/r8-optimized/MODULE.bazel new file mode 100644 index 0000000..717217b --- /dev/null +++ b/examples/r8-optimized/MODULE.bazel
@@ -0,0 +1,38 @@ +module( + name = "r8app", +) + +bazel_dep(name = "rules_java", version = "9.0.3") +bazel_dep(name = "bazel_skylib", version = "1.8.1") +bazel_dep(name = "rules_jvm_external", version = "6.7") + +bazel_dep( + name = "rules_android", + version = "0.8.0", +) + + +# Local override to enable this app to be used for rules_android presubmit +# integration testing. If you're basing your app's MODULE file on this +# example, you do *not* need the following override. +local_path_override( + module_name = "rules_android", + path = "../../", +) + +remote_android_extensions = use_extension( + "@rules_android//bzlmod_extensions:android_extensions.bzl", + "remote_android_tools_extensions") +use_repo(remote_android_extensions, "android_tools") + +android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension") +use_repo(android_sdk_repository_extension, "androidsdk") + +register_toolchains("@androidsdk//:sdk-toolchain", "@androidsdk//:all") + +# NOTE: It's not actually necessary to add protobuf as a dep to the example app. +# This is only here to enable setting --@protobuf//bazel/flags:prefer_prebuilt_protoc +# in order to make internal presubmit faster. This quirk is really only relevant +# to protobuf ~33.4 or so, as that flag will become true by default in 34+. +# See https://protobuf.dev/news/2026-01-16/ +bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf")
diff --git a/examples/r8-optimized/README.md b/examples/r8-optimized/README.md new file mode 100644 index 0000000..0f809a3 --- /dev/null +++ b/examples/r8-optimized/README.md
@@ -0,0 +1,60 @@ +# R8 Optimized Android App Example + +This example demonstrates how to build and optimize a simple Android application using **R8**. + +## What is R8 and Why Use It? + +[R8](https://developer.android.com/build/shrink-code) is the code shrinker, optimizer, and dexer for Android developed by Google. In a single step, R8 handles: + +- **Code Shrinking (Tree Shaking)**: Detects and safely removes unused classes, methods, fields, and attributes from your application and third-party dependencies. +- **Code Optimization**: Inspects and rewrites code to improve runtime performance, inline methods, remove dead branches, and eliminate unused arguments. +- **Name Obfuscation**: Renames types and members with short names to minimize DEX size. +- **Resource Shrinking**: When paired with `shrink_resources = True`, removes unused Android resources that are no longer referenced after code shrinking. +- **Dexing**: Directly converts Java bytecode to optimized Android DEX format. + +Using R8 significantly reduces APK/AAB download and install sizes and memory footprint, decreases app startup time, and keeps method counts within optimal limits. + +For in-depth details on configuring ProGuard/R8 keep rules and optimization flags, see [docs/r8-optimization.md](../../docs/r8-optimization.md). + +## Building the Targets + +Ensure that the `ANDROID_HOME` environment variable is set to the path of your Android SDK: + +```bash +export ANDROID_HOME=/path/to/android/sdk +``` + +### 1. Build the Optimized APK (`android_binary`) + +To build the standalone optimized APK: + +```bash +bazel build //:r8_app +``` + +Output: `bazel-bin/r8_app.apk` + +### 2. Build the Optimized Android App Bundle (`android_application`) + +To build the optimized Android App Bundle (AAB): + +```bash +bazel build //:r8_app_bundle +``` + +Output: `bazel-bin/r8_app_bundle_unsigned.aab` + +### 3. Fast Incremental Installation with Mobile-Install + +To build and install the application directly onto a connected Android device or running emulator: + +```bash +bazel mobile-install //:r8_app +``` + +## Configuration Files + +- **`BUILD`**: Defines the `android_binary` (`r8_app`) and `android_application` (`r8_app_bundle`) targets with `proguard_specs` and `shrink_resources = True`. +- **`proguard-rules.pro`**: App-specific keep rules for preserving entry points like `MainActivity`. +- **`proguard-android-optimize.txt`**: Default Android optimization rules for R8. +- **`.bazelrc`**: Flags and settings needed to build the app with `rules_android`. \ No newline at end of file
diff --git a/examples/r8-optimized/WORKSPACE.bzlmod b/examples/r8-optimized/WORKSPACE.bzlmod new file mode 100644 index 0000000..5321e34 --- /dev/null +++ b/examples/r8-optimized/WORKSPACE.bzlmod
@@ -0,0 +1 @@ +workspace(name = "r8app")
diff --git a/examples/r8-optimized/java/com/r8app/AndroidManifest.xml b/examples/r8-optimized/java/com/r8app/AndroidManifest.xml new file mode 100644 index 0000000..f9d853e --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/AndroidManifest.xml
@@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.r8app" > + + <uses-sdk + android:minSdkVersion="21" + android:targetSdkVersion="36" /> + + <application + android:allowBackup="true" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" > + <activity + android:name="com.r8app.MainActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest>
diff --git a/examples/r8-optimized/java/com/r8app/BUILD b/examples/r8-optimized/java/com/r8app/BUILD new file mode 100644 index 0000000..62f8821 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/BUILD
@@ -0,0 +1,17 @@ +load( + "@rules_android//android:rules.bzl", + "android_library", +) + +exports_files([ + "AndroidManifest.xml", + "bundle_config.pb.json", +]) + +android_library( + name = "r8_lib", + srcs = ["MainActivity.java"], + manifest = "AndroidManifest.xml", + resource_files = glob(["res/**"]), + visibility = ["//:__pkg__"], +)
diff --git a/examples/r8-optimized/java/com/r8app/MainActivity.java b/examples/r8-optimized/java/com/r8app/MainActivity.java new file mode 100644 index 0000000..442b823 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/MainActivity.java
@@ -0,0 +1,59 @@ +// Copyright 2022 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.r8app; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +/** + * The main activity of the R8 Sample App. + */ +public class MainActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main_activity); + + final Button buttons[] = { + findViewById(R.id.button_id_fizz), findViewById(R.id.button_id_buzz), + }; + + for (var b : buttons) { + b.setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + TextView tv = findViewById(R.id.text_hello); + if (v.getId() == R.id.button_id_fizz) { + tv.setText("fizz"); + } else if (v.getId() == R.id.button_id_buzz) { + tv.setText("buzz"); + } + } + }); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu, menu); + return true; + } +}
diff --git a/examples/r8-optimized/java/com/r8app/bundle_config.pb.json b/examples/r8-optimized/java/com/r8app/bundle_config.pb.json new file mode 100644 index 0000000..2d5b540 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/bundle_config.pb.json
@@ -0,0 +1,12 @@ +// https://github.com/google/bundletool/blob/master/src/main/proto/config.proto +{ + "optimizations": { + "splitsConfig": { + "splitDimension": [ + { + "value": "LANGUAGE" + } + ] + } + } +}
diff --git a/examples/r8-optimized/java/com/r8app/res/drawable-hdpi/ic_launcher.png b/examples/r8-optimized/java/com/r8app/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..6ab2add --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/drawable-hdpi/ic_launcher.png Binary files differ
diff --git a/examples/r8-optimized/java/com/r8app/res/drawable-mdpi/ic_launcher.png b/examples/r8-optimized/java/com/r8app/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..c0a73c3 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/drawable-mdpi/ic_launcher.png Binary files differ
diff --git a/examples/r8-optimized/java/com/r8app/res/drawable-xhdpi/ic_launcher.png b/examples/r8-optimized/java/com/r8app/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..014b0f1 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/drawable-xhdpi/ic_launcher.png Binary files differ
diff --git a/examples/r8-optimized/java/com/r8app/res/drawable-xxhdpi/ic_launcher.png b/examples/r8-optimized/java/com/r8app/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..20703a1 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/drawable-xxhdpi/ic_launcher.png Binary files differ
diff --git a/examples/r8-optimized/java/com/r8app/res/layout/main_activity.xml b/examples/r8-optimized/java/com/r8app/res/layout/main_activity.xml new file mode 100644 index 0000000..f84199c --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/layout/main_activity.xml
@@ -0,0 +1,23 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <TextView + android:id="@+id/text_hello" + android:text="@string/hello_world" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <Button + android:id="@+id/button_id_fizz" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="fizz" /> + <Button + android:id="@+id/button_id_buzz" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="buzz" /> + +</LinearLayout>
diff --git a/examples/r8-optimized/java/com/r8app/res/menu/menu.xml b/examples/r8-optimized/java/com/r8app/res/menu/menu.xml new file mode 100644 index 0000000..02ec528 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/menu/menu.xml
@@ -0,0 +1,8 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + tools:context="com.r8app.MainActivity" > + <item android:id="@+id/action_settings" + android:title="@string/action_settings" + android:orderInCategory="100" /> +</menu>
diff --git a/examples/r8-optimized/java/com/r8app/res/values-b+es/strings.xml b/examples/r8-optimized/java/com/r8app/res/values-b+es/strings.xml new file mode 100644 index 0000000..986ffd6 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/values-b+es/strings.xml
@@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="hello_world" translatable="false">¡Hola Mundo!</string> +</resources>
diff --git a/examples/r8-optimized/java/com/r8app/res/values/dimens.xml b/examples/r8-optimized/java/com/r8app/res/values/dimens.xml new file mode 100644 index 0000000..47c8224 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/values/dimens.xml
@@ -0,0 +1,5 @@ +<resources> + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> +</resources>
diff --git a/examples/r8-optimized/java/com/r8app/res/values/strings.xml b/examples/r8-optimized/java/com/r8app/res/values/strings.xml new file mode 100644 index 0000000..31dac87 --- /dev/null +++ b/examples/r8-optimized/java/com/r8app/res/values/strings.xml
@@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_name" translatable="false">r8app</string> + <string name="hello_world" translatable="false">Hello world!</string> + <string name="action_settings" translatable="false">Settings</string> + +</resources>
diff --git a/examples/r8-optimized/proguard-android-optimize.txt b/examples/r8-optimized/proguard-android-optimize.txt new file mode 100644 index 0000000..9894014 --- /dev/null +++ b/examples/r8-optimized/proguard-android-optimize.txt
@@ -0,0 +1,84 @@ +# These are the baseline recommended ProGuard / R8 settings for Android apps. +# See https://developer.android.com/r/tools/r8/keep-rules for more details. +# Do not edit this file. Add custom rules for your project to proguard-rules.pro. + +-allowaccessmodification + +# Preserve some attributes that may be required for reflection. +-keepattributes AnnotationDefault, + EnclosingMethod, + InnerClasses, + RuntimeVisibleAnnotations, + RuntimeVisibleParameterAnnotations, + RuntimeVisibleTypeAnnotations, + Signature + +-keep public class com.google.vending.licensing.ILicensingService +-keep public class com.android.vending.licensing.ILicensingService +-keep public class com.google.android.vending.licensing.ILicensingService +-dontnote com.android.vending.licensing.ILicensingService +-dontnote com.google.vending.licensing.ILicensingService +-dontnote com.google.android.vending.licensing.ILicensingService + +# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native +-keepclasseswithmembernames,includedescriptorclasses class * { + native <methods>; +} + +# Keep setters in Views so that animations can still work. +-keepclassmembers public class * extends android.view.View { + void set*(***); + *** get*(); +} + +# We want to keep methods in Activity that could be used in the XML attribute onClick. +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keepclassmembers class * implements android.os.Parcelable { + public static final ** CREATOR; +} + +# Preserve annotated Javascript interface methods. +-keepclassmembers class * { + @android.webkit.JavascriptInterface <methods>; +} + +# The support libraries contains references to newer platform versions. +# Don't warn about those in case this app is linking against an older +# platform version. We know about them, and they are safe. +-dontnote android.support.** +-dontnote androidx.** +-dontwarn android.support.** +-dontwarn androidx.** + +# Understand the @Keep support annotation. +-keep class android.support.annotation.Keep + +-keep @android.support.annotation.Keep class * {*;} + +-keepclasseswithmembers class * { + @android.support.annotation.Keep <methods>; +} + +-keepclasseswithmembers class * { + @android.support.annotation.Keep <fields>; +} + +-keepclasseswithmembers class * { + @android.support.annotation.Keep <init>(...); +} + +# These classes are duplicated between android.jar and org.apache.http.legacy.jar. +-dontnote org.apache.http.** +-dontnote android.net.http.** + +# These classes are duplicated between android.jar and core-lambda-stubs.jar. +-dontnote java.lang.invoke.**
diff --git a/examples/r8-optimized/proguard-rules.pro b/examples/r8-optimized/proguard-rules.pro new file mode 100644 index 0000000..f8fcb03 --- /dev/null +++ b/examples/r8-optimized/proguard-rules.pro
@@ -0,0 +1,6 @@ +# Proguard / R8 configuration for r8app + +# Keep the entry point activity +-keep class com.r8app.MainActivity { + <init>(...); +}