-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Android] Add support for split build per architecture #5160
Conversation
cc @satya164, @brentvatne Who I think asked about this before the holidays. |
@mkonicek This is so cool. Will test this ASAP. |
splits { | ||
abi { | ||
enable true | ||
reset() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do and do we really need it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reset(): reset the list of ABIs to be included to an empty string (this allows, in conjunctions with include, to indicate which one to use rather than which ones to ignore)
From http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be we should add a comment there, with the link?
Just tested this. Working fine. Reduced APK size to 8.4 MB (arm) and 9.5 MB (x86) from 11.6 MB for me (without proguard) :) |
@mkonicek perhaps we should also turn on proguard by default for release builds. If people are only writing JS they are not going to be affected, and people writing code probably already have it on. That would probably be a separate PR, though. |
I could never get proguard working though, facing the following issues, :app:generateReleaseSources
:app:processReleaseJavaRes UP-TO-DATE
:app:compileReleaseJavaWithJavac
:app:compileReleaseNdk UP-TO-DATE
:app:proguardRelease
Warning: com.facebook.react.bridge.CatalystInstance$1: can't find referenced method 'void access$200(com.facebook.react.bridge.CatalystInstance,com.facebook.react.bridge.JavaScriptExecutor,com.facebook.react.bridge.JavaScriptModulesConfig)' in program class com.facebook.react.bridge.CatalystInstance
Warning: com.facebook.react.bridge.CatalystInstance$1: can't find enclosing method 'CatalystInstance(com.facebook.react.bridge.queue.CatalystQueueConfigurationSpec,com.facebook.react.bridge.JavaScriptExecutor,com.facebook.react.bridge.NativeModuleRegistry,com.facebook.react.bridge.JavaScriptModulesConfig,com.facebook.react.bridge.JSBundleLoader,com.facebook.react.bridge.NativeModuleCallExceptionHandler)' in program class com.facebook.react.bridge.CatalystInstance
Warning: com.facebook.react.bridge.queue.MessageQueueThread$1: can't find enclosing method 'com.facebook.react.bridge.queue.MessageQueueThread startNewBackgroundThread(java.lang.String,com.facebook.react.bridge.queue.QueueThreadExceptionHandler)' in program class com.facebook.react.bridge.queue.MessageQueueThread
Warning: com.facebook.react.devsupport.DevServerHelper$3$1: can't find enclosing method 'void onFailure(com.squareup.okhttp.Request,java.io.IOException)' in program class com.facebook.react.devsupport.DevServerHelper$3
Warning: com.facebook.react.modules.storage.AsyncStorageModule$7: can't find referenced method 'boolean access$100(com.facebook.react.modules.storage.AsyncStorageModule)' in program class com.facebook.react.modules.storage.AsyncStorageModule
Warning: com.facebook.react.modules.storage.AsyncStorageModule$7: can't find referenced method 'com.facebook.react.modules.storage.ReactDatabaseSupplier access$000(com.facebook.react.modules.storage.AsyncStorageModule)' in program class com.facebook.react.modules.storage.AsyncStorageModule
Warning: com.facebook.react.uimanager.UIManagerModule$2: can't find referenced method 'com.facebook.react.uimanager.NativeViewHierarchyManager access$200(com.facebook.react.uimanager.UIManagerModule)' in program class com.facebook.react.uimanager.UIManagerModule
Warning: there were 7 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
Exception while processing task
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:473)
at proguard.ProGuard.initialize(ProGuard.java:233)
at proguard.ProGuard.execute(ProGuard.java:98)
at proguard.gradle.ProGuardTask.proguard(ProGuardTask.java:1074)
at com.android.build.gradle.tasks.AndroidProGuardTask.doMinification(AndroidProGuardTask.java:139)
at com.android.build.gradle.tasks.AndroidProGuardTask$1.run(AndroidProGuardTask.java:115)
at com.android.builder.tasks.Job.runTask(Job.java:48)
at com.android.build.gradle.tasks.SimpleWorkQueue$EmptyThreadContext.runTask(SimpleWorkQueue.java:41)
at com.android.builder.tasks.WorkQueue.run(WorkQueue.java:227)
at java.lang.Thread.run(Thread.java:745)
:app:dexRelease
:app:validateReleaseSigning
:app:packageArmeabi-v7aRelease FAILED |
@mkonicek updated the pull request. |
3 similar comments
@mkonicek updated the pull request. |
@mkonicek updated the pull request. |
@mkonicek updated the pull request. |
This allows everyone to deploy significantly smaller APKs by building separate APKs for ARM, x86 architectures. For a simple app, Both ARM, x86 APKs are about 4MB which is about 50% reduction compared to the universal APK. Test Plan: Created a sample project, uncommented `// include "armeabi-v7a", 'x86'`. cd android ./gradlew assembleDebug Three APKs were created, unzipped each: one has only x86 binaries, one has ARM binaries, one has both. ./gradlew assembleRelease Three APKs were created, JS bundle is correcly added to assets. react-native run-android The correct APK is installed on the emulator and the app runs (Gradle output: "Installing APK 'app-x86-debug.apk'"). With the line commented out the behavior is exactly the same as before, only one universal APK is built. Checked that version codes are set correctly as decribed in http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits http://developer.android.com/intl/ru/google/play/publishing/multiple-apks.html aapt l -a ../android/app/build/outputs/apk/app-armeabi-v7a-debug.apk | grep android:version A: android:versionCode(0x0101021b)=(type 0x10)0x100001 A: android:versionName(0x0101021c)="1.0" (Raw: "1.0") aapt l -a ../android/app/build/outputs/apk/app-x86-debug.apk | grep android:version A: android:versionCode(0x0101021b)=(type 0x10)0x200001 A: android:versionName(0x0101021c)="1.0" (Raw: "1.0") aapt l -a ../android/app/build/outputs/apk/app-universal-debug.apk | grep android:version A: android:versionCode(0x0101021b)=(type 0x10)0x1 A: android:versionName(0x0101021c)="1.0" (Raw: "1.0")
@mkonicek updated the pull request. |
@facebook-github-bot shipit |
Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/937315382983788/int_phab to review. |
@mkonicek Thanks. Proguard works after applying that fix (further reduced APK size about 1MB). |
Summary: This allows everyone to deploy significantly smaller APKs to they Play Store by building separate APKs for ARM, x86 architectures. For a simple app, a release APK minified with Produard: - Universal APK is **7MB** - x86 APK is **4.6MB** (34% reduction) - ARM APK is **3.7MB** (47% reduction) Created a sample project, uncommented `// include "armeabi-v7a", 'x86'`: cd android ./gradlew assembleDebug Three APKs were created, unzipped each: one has only x86 binaries, one has ARM binaries, one has both. ./gradlew assembleRelease Three APKs were created, JS bundle is correcly added to assets. react-native run-android The correct APK is installed on the emulator and the app runs fine (Gradle output: "Installing APK 'app-x86-debug.apk'"). With the line commented out the behavior is exactly the same as before, only one universal APK is built. Checked that version codes are set correctly as described in http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits http://developer.android.com/intl/ru/google/play/publishing/multiple-apks.html Closes #5160 Reviewed By: svcscm Differential Revision: D2811443 Pulled By: mkonicek fb-gh-sync-id: 97b22b9cd567e53b8adac36669b90768458b7a55
@satya164 proguard already runs after this fix or you modified something for it? |
Note for users getting "This app is incompatible with your device." on the Play Store after uploading their two working APKs (with You should see a message saying Some devices are eligible to run multiple APKs. In such a scenario, the device will receive the APK with the higher version code. |
@antoinerousseau Proguard runs fine without any customizations in latest release. |
Summary: This allows everyone to deploy significantly smaller APKs to they Play Store by building separate APKs for ARM, x86 architectures. For a simple app, a release APK minified with Produard: - Universal APK is **7MB** - x86 APK is **4.6MB** (34% reduction) - ARM APK is **3.7MB** (47% reduction) Created a sample project, uncommented `// include "armeabi-v7a", 'x86'`: cd android ./gradlew assembleDebug Three APKs were created, unzipped each: one has only x86 binaries, one has ARM binaries, one has both. ./gradlew assembleRelease Three APKs were created, JS bundle is correcly added to assets. react-native run-android The correct APK is installed on the emulator and the app runs fine (Gradle output: "Installing APK 'app-x86-debug.apk'"). With the line commented out the behavior is exactly the same as before, only one universal APK is built. Checked that version codes are set correctly as described in http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits http://developer.android.com/intl/ru/google/play/publishing/multiple-apks.html Closes facebook/react-native#5160 Reviewed By: svcscm Differential Revision: D2811443 Pulled By: mkonicek fb-gh-sync-id: 97b22b9cd567e53b8adac36669b90768458b7a55
This allows everyone to deploy significantly smaller APKs to the Play Store by building separate APKs for ARM, x86 architectures.
For a simple app, a release APK minified with Produard:
Test Plan:
Created a sample project, set
enableSeparateBuildPerCPUArchitecture = true
:Three APKs were created, unzipped each: one has only x86 binaries,
one has ARM binaries, one has both.
In each APK the JS bundle is correctly present in assets.
The correct APK is installed on the emulator and the app runs fine
(Gradle output: "Installing APK 'app-x86-debug.apk'").
With
enableSeparateBuildPerCPUArchitecture = false
the behavior is exactly the same as before,only one universal APK is built.
Checked that version codes are set correctly as decribed in
http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
http://developer.android.com/intl/ru/google/play/publishing/multiple-apks.html