I'm using proguard to reduce my apk size. The debug apk reduce from 90mb to 55mb, but the signed apk is 71mb. Here is my build.gradle code:
apply plugin: 'com.android.application'
android {
signingConfigs {
XXXX {
keyAlias 'xxxx'
keyPassword 'xxxx'
storeFile file('/Users/xxxx.jks')
storePassword 'xxxxxx'
}
}
compileSdkVersion 23
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "com.xxxx"
minSdkVersion 14
targetSdkVersion 22
versionCode 61
versionName "4.1.8.1"
multiDexEnabled true
signingConfig signingConfigs.XXXX
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.XXXX
}
debug {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.XXXX
}
}
productFlavors {
}
dexOptions {
javaMaxHeapSize "4g"
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
}
}
and
repositories {
mavenLocal()
maven {
name "jcenter"
url "http://jcenter.bintray.com/"
}
}
dependencies {
...
}
Further explaining sosite's answer, it seems that this happens only if comparing a debug apk built via Run or Debug meant for a specific device (even without Instant Run enabled) instead of a debugapk built via Build > Build APK (for any supported device).
Any variant (even debug itself) built via Build APK will include all the resources for that variant. Also, the Run/Debug apk includes pre-dexed classes specific for that single device, while Build APK ones includes only some general pre-dexed classes that the compiler determines safe for all supported devices - the full dexing only occurs in the device itself, when the apk is installed.
I've zipdiff-ed an apk generated via Debug with another via Build APK for the same variant of the same project and published the simplified output for demonstration (also available as html).
When you build your app locally for specific type of phone then Android Studio attach only necessary resource files. When you build release version then you have attached all types of drawables so you app file size can increase drastically.
I suggest you to use jpg in place of png in as many places as you can and compress them of course - often I use tinyPNG website or just Photoshop ;)
Related
I was trying to upload the apk since 2 days. Every time I upload the apk I get the 64 bit error. I know there are other questions on Stackoverflow asking the same thing. But most of them saying the solution for flutter.
As per the Google Documentation I used APK Analyze and found that there are .so files in my project.
Based on documentation I added ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'. But Still I get the same error.
Please check my build.gradle code.
android {
compileSdkVersion 29
buildToolsVersion '29.0.0'
defaultConfig {
applicationId "com.XXXXX"
minSdkVersion 15
targetSdkVersion 29
versionCode 237
versionName "3.3.20"
multiDexEnabled true
//ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86_64' - not worked
ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
flavorDimensions "default"
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dexOptions {
jumboMode true
javaMaxHeapSize "4g"
}
productFlavors {
production {
applicationId 'com.XXXXX'
}
staging {
applicationId 'com.XXXXX.staging'
}
}
// Add this block and enable/disable the parameters as follows
bundle {
density {
// Different APKs are generated for devices with different screen densities; true by default.
enableSplit true
}
abi {
// Different APKs are generated for devices with different CPU architectures; true by default.
enableSplit true
}
language {
// This is disabled so that the App Bundle does NOT split the APK for each language.
// We're gonna use the same APK for all languages.
enableSplit false
}
}}
Please help me to solve the issue.
After signed bundle apk creation the .so files are showing same in armeabi-v7a, arm64-v8a, x86, x86_64 folders.
I tried many solution but didn't work. Later I found that there is a RETAINED APK is existing in play console release and which has 32 bit. Then I deactivated it and uploaded the new apk & It worked successfully
If you say you "found that there are .so files" I assume your project is not compiling but only using them. You then need this native libraries for the missing architectures from the NDK project which produced this libraries. It can't be done just by a different config in your project.
No need to add this line ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64' (Remove this line)
please add this code in your build.gradle file
-After Release Apk you got 2 file of apk in your release folder
-now you can use app-arm64-v8a-release.apk for playstore release
-I hope this is useful for you
android {
lintOptions{
....
}
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'
universalApk false
}
}
}
hi friend i got another way for build 32 and 64 bit release app or bundle.
please add this code your build.gradle file
defaultConfig {
applicationId "com.XXXXX"
minSdkVersion 15
targetSdkVersion 29
versionCode 237
versionName "3.3.20"
multiDexEnabled true
ndk {
abiFilters 'arm64-v8a', 'x86_64'
}
}
note: remove below function
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'
universalApk false
}
}
Okay so I am trying to get my react-native into an apk file and install it on a device the assembleRelease works fine but it seems like it doesn't get the signing since I can only install the debug version and not installRelease which gives me the error
Task 'installRelease' not found in root project 'timeReportTool'. Some candidates are: 'uninstallRelease'.
here is the Android block from my build.gradle
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.timereporttool"
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
signingConfigs {
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.release // add this line as well
}
}...
I do get an app-release-unsigned.apk so it is clearly not getting signed in Android studios it can't sync the gradle because of this line that were there from the start
apply from: "../../node_modules/react-native/react.gradle"
in Android Studio the node modules map is empty but it exists in the directory
You have to create a signing key and reference it in your project, as described here: https://facebook.github.io/react-native/docs/signed-apk-android
It's crazy that no one answered this for over a year. There's no way around this issue if you publish a React-Native app to the Play Store.
It's due to unsigned code. You have to follow some sort of steps mentioned in the react native official website for generating a signed apk. Otherwise, even though the apk is created, the user not able to install it on their device.
Refer the following link for generating signed apk.
Publishing to Google Play Store
I tried to test the release build of the app. So I have added the below config to build.gradle of my app. But that didn't make any effect. Test always runs on debug build
android {
compileSdkVersion 24
buildToolsVersion "24.0.0"
defaultConfig {
applicationId "com.****.****"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0 Beta"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
testBuildType "release"
signingConfigs {
release {
keyAlias '******'
keyPassword '*****'
storeFile file('path to keystore')
storePassword '*****'
}
}
buildTypes {
release {
minifyEnabled true
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
multiDexEnabled true
}
}
}
When searched for answers in other SO thread I found testBuildType "release" will run test on release build but it did not work
I'm not sure I got it all, but a few things :
You can test your release with the build variant menu on Android studio (menu at the bottom left) (#Sagar Chavada suggestion)
When you generate your signed apk with Android studio you can choose at the end the build type, release in your case
I know it's for testing purpose but debuggable true in your realease build won't allow you to push it on Google play
Whenever you are building a project and want to create a signed apk then
Add following code in to android {} in your build.gradle file.
productFlavors {
RELEASE {
applicationIdSuffix ".release"
versionNameSuffix "-release"
}
DEBUG {
applicationIdSuffix ".debug"
versionNameSuffix "-debug"
}
}
Go to Android SDK --> Build.
Tap on Generate Signed APK
It will ask to create a debug or Signed build (apk format)
Then select release flavour and generate apk.
I am working for a company which has this "foo" app on the store, the app is a helper for our hardware which is revelled by resellers. We made sure that the name is as generic as possible - in order for our vendors to be able to market the app as "their app".
However - some re-sellers do want to have their exact name and icon on the app. And they are willing to pay so, I need to make this happen.
Questions:
I understand that I am looking for build variants. But still, how can I modify the apk-package-name , display name is default launcher icon using build variants?
Is this permitted...? I am not "officially" spamming the store, but it feels like I could get banned for doing that exactly.
Code signing - I will upload the APK my self, and I will need to sign using different certificates (whatever it's called on android). Again - this is vague, and I cannot find documentation on this subject.
I also plan on releasing a beta version of my app in this way. I am currently using the standard mechanism, but this means that testers cannot show case the app to customers (as it's not finished or crashing most of the time) [1]
Does the term "white labeling" apply here...?
[1] the joys of working in a small company :)
You can do this with build variants as you suspected but also you would likely need Flavors.
Here is an example gradle file that has multiple build types and flavors. You set the ApplicationId (packagename used in Play Store) in the flavor settings.
Set up the signing in each type/flavor. You can add resources, icons, manifests etc that are specific to each flavor. You can even replace whole class files so customer specific code is only included in the apk for the customer you are building for.
defaultConfig {
applicationId "uk.co.foo.default"
minSdkVersion 14
targetSdkVersion 23
versionCode = 113
versionName = "3.2.3"
}
signingConfigs {
release {
storeFile file("X:\\Android Projects\\Keystore\\MyKeys.jks")
storePassword "MyPassword"
keyAlias "KeyAlias"
keyPassword "itsasecret"
}
}
productFlavors {
Customer1 {
applicationId "uk.co.foo.customer1"
}
Customer2 {
applicationId "uk.co.foo.customer2"
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix " Debug"
}
beta {
applicationIdSuffix ".beta"
versionNameSuffix " Beta"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
signed {
minifyEnabled false
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
Here is the folder structure for adding resources for each type\flavor. In this example, the second flavor is called "fan". The "main" folder is used by default. Each type and flavors resources are merged into the apk (replacing any of the same name in the main folder) depending on which build you choose in the "Build Variants" section of Android Studio.
Android Studio will display which folders are in effect for the current build as shown highlighted in this image.
Edit - full official documentation is available here: https://developer.android.com/tools/building/configuring-gradle.html
Whenever I set the value of "debugging" to "true" in my android app, there is an error.
The description of the error is: "Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one".
Get rid of android:debuggable="true" from your manifest.
First, you probably don't need it. Even with Eclipse, normal IDE builds are automatically debuggable, as is any process on an emulator. A release build, on production hardware, would not be debuggable, which is what you want, for security reasons.
If you need more flexibility than that, and you are using Android Studio/Gradle for Android, set up custom build types in build.gradle to model your other scenarios. The default debug build type will make the app be debuggable; the default release build type would make your app not debuggable. Custom build types can use the debuggable statement to state what they should do:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.2'
}
}
apply plugin: 'com.android.application'
dependencies {
}
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
versionCode 2
versionName "1.1"
minSdkVersion 14
targetSdkVersion 18
}
signingConfigs {
release {
storeFile file('HelloConfig.keystore')
keyAlias 'HelloConfig'
storePassword 'laser.yams.heady.testy'
keyPassword 'fw.stabs.steady.wool'
}
}
buildTypes {
debug {
applicationIdSuffix ".d"
versionNameSuffix "-debug"
}
release {
signingConfig signingConfigs.release
}
mezzanine.initWith(buildTypes.release)
mezzanine {
applicationIdSuffix ".mezz"
debuggable true
}
}
}
Here, I say that my mezzanine custom build type should be debuggable, via debuggable true in its definition.