Full form of APK is Android Package Kit. The APK file is a generated package file containing all the important files which is recommended to run android app on android mobile device. By default when we create react native project app and install that app on our device – Emulator then the app install as Debug Mode. But we cannot get the Signed Release Android APK and without the original APK file we cannot upload this file on Google Play Store. There is also a problem that all the react native beginners is facing that the Un-Signed APK cannot run without the JS server. So using the Singed APK we can run our react native android app to any android mobile device without running the JS Server and upload .APK file to Google Play Store. So in this tutorial we would going to Generate signed release android APK that run without JS Server in React Native in Windows PC using Key Store.
Contents in this tutorial Generate signed release android APK that run without JS Server in React Native:
1. Start Command Prompt(CMD) in Windows with Administrator Mode.
3. Run the below command in bin directory in Command Prompt.
1 |
keytool -genkey -v -keystore release-key.keystore -alias key-alias -keyalg RSA -keysize 2048 -validity 10000 |
4. After entering the above command in bin directory in It will ask some information about your application.
Note: Remember the password your enter while creating release-key.keystore file. Because it will use in below steps.
I am sharing the screenshot below.
5. After successfully done all the procedure the generated release-key.keystore file would store in C:\Program Files\Java\jdk1.8.0_92\bin folder.
6. Copy the release-key.keystore file from bin folder and paste inside the YourReactNativeProject -> android -> app folder like i did in below screenshot.
7. Open the gradle.properties file present in YourReactNativeProject -> android.
8. Paste the below code inside the gradle.properties file.
1 2 3 4 |
MYAPP_RELEASE_STORE_FILE=release-key.keystore MYAPP_RELEASE_KEY_ALIAS=key-alias MYAPP_RELEASE_STORE_PASSWORD=1234567890 MYAPP_RELEASE_KEY_PASSWORD=1234567890 |
Code of my projects gradle.properties file after adding above code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true android.useDeprecatedNdk=true MYAPP_RELEASE_STORE_FILE=release-key.keystore MYAPP_RELEASE_KEY_ALIAS=key-alias MYAPP_RELEASE_STORE_PASSWORD=1234567890 MYAPP_RELEASE_KEY_PASSWORD=1234567890 |
9. Open the build.gradle file present inside YourReactNativeProject -> android -> app folder.
10. Add below code inside the build.gradle file in android scope.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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 } } } buildTypes { release { minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" signingConfig signingConfigs.release } } |
11. Code of my project’s build.gradle file after adding above code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
apply plugin: "com.android.application" import com.android.build.OutputFile /** * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets * and bundleReleaseJsAndAssets). * These basically call `react-native bundle` with the correct arguments during the Android build * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the * bundle directly from the development server. Below you can see all the possible configurations * and their defaults. If you decide to add a configuration block, make sure to add it before the * `apply from: "../../node_modules/react-native/react.gradle"` line. * * project.ext.react = [ * // the name of the generated asset file containing your JS bundle * bundleAssetName: "index.android.bundle", * * // the entry file for bundle generation * entryFile: "index.android.js", * * // whether to bundle JS and assets in debug mode * bundleInDebug: false, * * // whether to bundle JS and assets in release mode * bundleInRelease: true, * * // whether to bundle JS and assets in another build variant (if configured). * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants * // The configuration property can be in the following formats * // 'bundleIn${productFlavor}${buildType}' * // 'bundleIn${buildType}' * // bundleInFreeDebug: true, * // bundleInPaidRelease: true, * // bundleInBeta: true, * * // whether to disable dev mode in custom build variants (by default only disabled in release) * // for example: to disable dev mode in the staging build type (if configured) * devDisabledInStaging: true, * // The configuration property can be in the following formats * // 'devDisabledIn${productFlavor}${buildType}' * // 'devDisabledIn${buildType}' * * // the root of your project, i.e. where "package.json" lives * root: "../../", * * // where to put the JS bundle asset in debug mode * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", * * // where to put the JS bundle asset in release mode * jsBundleDirRelease: "$buildDir/intermediates/assets/release", * * // where to put drawable resources / React Native assets, e.g. the ones you use via * // require('./image.png')), in debug mode * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", * * // where to put drawable resources / React Native assets, e.g. the ones you use via * // require('./image.png')), in release mode * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", * * // by default the gradle tasks are skipped if none of the JS files or assets change; this means * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to * // date; if you have any other folders that you want to ignore for performance reasons (gradle * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ * // for example, you might want to remove it from here. * inputExcludes: ["android/**", "ios/**"], * * // override which node gets called and with what additional arguments * nodeExecutableAndArgs: ["node"], * * // supply additional arguments to the packager * extraPackagerArgs: [] * ] */ project.ext.react = [ entryFile: "index.js" ] apply from: "../../node_modules/react-native/react.gradle" /** * Set this to true to create two separate APKs instead of one: * - An APK that only works on ARM devices * - An APK that only works on x86 devices * The advantage is the size of the APK is reduced by about 4MB. * Upload all the APKs to the Play Store and people will download * the correct one based on the CPU architecture of their device. */ def enableSeparateBuildPerCPUArchitecture = false /** * Run Proguard to shrink the Java bytecode in release builds. */ def enableProguardInReleaseBuilds = false android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "com.mynewproject" 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 } } // applicationVariants are e.g. debug, release applicationVariants.all { variant -> variant.outputs.each { output -> // For each separate APK per architecture, set a unique version code as described here: // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits def versionCodes = ["armeabi-v7a":1, "x86":2] def abi = output.getFilter(OutputFile.ABI) if (abi != null) { // null for the universal-debug, universal-release variants output.versionCodeOverride = versionCodes.get(abi) * 1048576 + defaultConfig.versionCode } } } } dependencies { compile project(':react-native-linear-gradient') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:+" // From node_modules } // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { from configurations.compile into 'libs' } |
12. Now finally open your react native project folder in command prompt and execute the below command.
1 |
cd android && gradlew assembleRelease |
Screenshot of CMD after executing above command :
Here you go guys, the final signed release android APK file will created inside the YourReactNativeProject -> android -> app -> build -> outputs -> apk folder.
Happy Reading 🙂 . Now you can upload this file on Google play store and also run in any device without running the JS Server.
wow men you are my mentor, thanks for this tutorial, it really helps me a lot. keep on.
Welcome 🙂
Thank you very much!
please arrange your tutorial in a list way so it will be easy for us to search any tutorial.Thanks for your valuable efforts.
Thanks for your suggestion Manpal 🙂 .
Thank you very :)!
Welcome Asif 🙂
C:\Levy\ReactNative\FirstProject>cd android && gradlew assembleRelease
FAILURE: Build failed with an exception.
* Where:
Build file ‘C:\Levy\ReactNative\FirstProject\android\app\build.gradle’ line: 152
* What went wrong:
A problem occurred evaluating project ‘:app’.
> Could not find method signingConfigs() for arguments [build_6xegjwpq8w1c0p7ich
[email protected]] on project ‘:app’ of type org.gradle.api.Project.
* Try:
Run with –stacktrace option to get the stack trace. Run with –info or –debug
option to get more log output.
BUILD FAILED
Total time: 18.002 secs
—————————————————————-
any sugestions?
Paulo did you follow all the steps ?
What can i do if i forgot my keystore password?
sir, how to make apk release in RN 0.61,
it size to large, 34mb.
i want like your build apk size 7mb.
please help me.
im sorry bad english, im from indonesia.
How to generate ipa in react native
Shahryar I’ll soon post a new tutorial regarding to your query.