Developing a mobile application is only half the journey. In order for the user to install your app on their smartphone, you need to compile the source code into a ready-made installation file. In the ecosystem, Android this standard has long been the format APK (Android Package Kit). Despite the gradual transition of the industry to a more modern format AAB for publication on Google Play, the need to create classic APK files remains relevant for internal testing, distribution through third-party stores, or installation on devices that do not support the new standards.
Many novice developers face difficulties precisely at the stage of finalizing the project. It would seem that the code has been written, the resources have been added, but how exactly do you turn this folder structure into a single file that you can send to a friend or upload to the server? The build process is automated, but requires a correct understanding of the settings and key signing procedures. Without meeting these requirements, the system simply will not allow you to install the application on the device. Android Studio automated, but requires proper understanding of settings Gradle and key signing procedures. Without meeting these requirements, the system simply will not allow you to install the application on your device.
In this article we will analyze in detail the entire path from pressing a button in the menu to receiving the finished file on your hard drive. We'll look at the difference between debug and release versions, set up automatic signing, and learn how to find compiled artifacts in your computer's file system. Understanding these processes is critical for any Android developer.
Differences between Debug and Release builds
Before proceeding with the actual build, you need to clearly understand what type of file you need. Android Studio by default it offers two main types of build configuration: Debug and Release. The debug version is created quickly, does not optimize the code, and is signed with an automatic debug key that is generated by the development environment itself. This is ideal for the coding stage and quick testing on an emulator or connected phone.
However, if your goal is to distribute the application among users, the debug version is absolutely not suitable for you. Release-build includes full code optimization (minification and obfuscation via ProGuard or R8), removes debugging information and requires signing with your private cryptographic key. It is this key that identifies you as the author of the application and allows you to release updates in the future.
An attempt to install a release application signed with a debug key on a device that already has a version with a different key (or vice versa) will result in an installation error. The security system Android blocks such actions to prevent hackers from replacing applications.
โ ๏ธ Attention: Never publicly publish APK files collected in the mode
Debug. They contain debug information, are vulnerable to reverse engineering and can be easily compromised.
The choice of build type affects not only security, but also the size of the resulting file. Debug versions often weigh significantly more due to the lack of resource compression and the presence of overhead. For the final product, always choose a configuration Release.
Configuring the application signature (Signing Config)
The key step before saving the project to the APK is setting up the signature. Without a digital signature, the operating system will simply refuse to install the application. In modern versions Android Studio this process is greatly simplified by integrating settings directly into the assembly file build.gradle.
First, you need to create a keystore (Keystore). This is a file with the extension .jks or .keystorethat contains your private key and certificate. Keep this file in a safe place, preferably in an encrypted cloud or on external media, as losing it will make it impossible to update your application in the future.
To set up automatic build signing, open the file build.gradle (module level, usually app) of your project. You need to add a block signingConfigs inside the section android. Here you specify the path to the storage file, passwords and key alias.
android {...
signingConfigs {
release {
storeFile file('path/to/your/keystore.jks')
storePassword 'your_store_password'
keyAlias 'your_key_alias'
keyPassword 'your_key_password'
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Using this approach allows you to automate the process. You don't have to enter passwords manually each time through the graphical interface, which is especially convenient when setting up CI/CD pipelines. However, store passwords in your code with caution: for public repositories, it is better to use environment variables or a file local.propertiesthat is not captured by version control.
Use a local.properties file to store sensitive data such as keystore passwords. Add this file to .gitignore to avoid accidentally publishing secrets on GitHub.
Step-by-step guide for generating an APK file
When the signature settings are ready, you can proceed to directly creating the file. In the menu Android Studio there is a special wizard that will guide you through all the necessary steps. This method is most intuitive for those who prefer a graphical interface.
Go to the top menu and select Build, then Generate Signed Bundle / APK. A dialog box appears asking you to select an output format. Despite the fact that Google recommends Android App Bundle, for our purposes we select the option APK and click Next.
At the next stage, the wizard will ask you to specify the signature data. If you have already configured signingConfigs in Gradle, you can select them from the dropdown list. Otherwise, click the Create new...button to generate a new key right here. You will need to specify the name of the storage file, password, key name (alias), certificate expiration date and information about the owner (name, organization, country).
โ๏ธ Checklist before assembly
After selecting the key, the system will prompt you to select Build Variants. Make sure the checkbox is opposite release. You can also activate the option to install APK on the connected device immediately after assembly by selecting the appropriate checkbox Install APK. Click Finishto start the compilation process.
A panel Buildwill appear at the bottom of the screen, where the progress of Gradle tasks will be displayed. The process can take from a few seconds to several minutes depending on the power of your computer and the complexity of the project. Upon completion, you will see a success notification with a link to the folder with the file.
Search and extract the finished APK artifact
Sometimes the automatic window prompting you to open the folder does not appear, or you need to find older versions of assemblies. In this case, it is useful to know the exact directory structure of the project Android Studio. All compiled files are saved in a hidden folder build inside the application module.
The full path to the file usually looks like this: your_project/app/build/outputs/apk/release/. Inside this folder you will find a file with a name that is based on the module name and assembly type, for example app-release.apk. If you use division by processor architectures (ABI splits), then there may be several files: for armeabi-v7a, arm64-v8a and x86.
| Parameter | Description | Where to find |
|---|---|---|
| File name | Generated automatically | Outputs/apk folder |
| Size | Depends on resources and code | File properties |
| Signature | Developer certificate | APK properties (in the archiver) |
| Version | versionName from Gradle | File name or manifest |
For quick navigation, you can use the context menu in the project. Right-click on the folder in the project tree, select (or Finder on Mac), and then manually navigate to the path. This will save time when searching for the desired version among many artifacts. app in the project tree, select Open In -> Explorer (or Finder on Mac) and then manually navigate to the path build/outputs/apk. This will save time when searching for the desired version among many artifacts.
โ ๏ธ Attention: The folder
buildis often cleared when a task is completedClean Project. If you need to keep the APK for a long time, be sure to copy it to another directory outside the project structure.
Gradle version and configuration management
Version control of your application is carried out through a file build.gradle. Parameters versionCode and versionName play a critical role in the update process. versionCode is an integer that increases with each new build. The Android system uses it to determine whether a new version is more recent than the one installed.
versionName is the string representation of the version visible to the user (for example, "1.0.5"). It does not affect the update logic, but is important for marketing and informing users. Before each build of the release APK, make sure that versionCode incremented (increased), otherwise installation over the old version may not work or be prohibited by the application store.
What are ABI splits?
Splitting APKs by processor architecture allows you to reduce the file size. Instead of one universal APK containing libraries for all types of processors, separate files are created only for the required device architecture, which saves space on the userโs disk.
You can also configure resource compression and code obfuscation in the Gradle configuration. The block minifyEnabled true activates a tool R8that removes unused code and renames classes, making the application smaller and harder for attackers to analyze. This is standard practice for any release builds.
Frequent errors during assembly and their solutions
The compilation process does not always go smoothly. Developers often encounter errors that prevent them from creating APKs. One of the most common problems is a signature error, where the system cannot find the keystore or the password is incorrect. In the logs this is usually displayed as SigningException.
Another common problem is the Gradle process running out of memory. Building large projects requires significant resources. If you see the error OutOfMemoryError, try increasing the amount of memory allocated to Gradle by adding the line org.gradle.jvmargs=-Xmx2048m to the file gradle.properties in the root of the project.
Sometimes the build breaks due to dependency conflicts. The libraries you include may require different versions of the same components. In this case, analyzing the dependency tree using the command ./gradlew app:dependencies and explicitly specifying the required versions in the file will help. build.gradle.
Successful APK assembly depends on three factors: correct Gradle configuration, a valid signing key and a sufficient number of system resources for compilation.
Is it possible to build an APK without an Internet connection?
Yes, if all the necessary libraries and dependencies have already been downloaded to the local Gradle cache. When you first start the project, a connection is required to download the repositories, but subsequent builds can work offline when using the flag --offline.
What is the difference between APK and AAB?
APK is a ready-made installation file that can be launched on the device right away. AAB (Android App Bundle) is a publishing format for Google Play that the store uses to generate optimized APKs for a specific user's device. AAB cannot be installed directly on the phone without special processing.
How to check what my APK is signed with?
You can use the utility apksigner from the Android SDK Build-tools package. The command apksigner verify --verbose app-release.apk will show information about certificates, their expiration dates and signature algorithms.
Why does the APK file weigh so much?
The large size may be caused by unoptimized images, the inclusion of heavy libraries, or the inclusion of resources for all screen densities and languages. Use APK analysis in Android Studio (Build menu -> Analyze APK) to find the heaviest components.
Is it necessary to use ProGuard/R8?
For debug versions - no. For release versions, especially if the application will be published in the store, this is highly recommended to protect the code and reduce file size. However, for some libraries you may need to configure keep rules.