Create a minimal Android boilerplate from scratch
In this post, I will introduce how to create an Android application from the command line, without the help of any IDE such as Android Studio.
If you are new to Android development, by following this post, I believe you will have a better understanding of how an Android application is constructed and how it works.
If you are already familiar with Android development, you might feel this post useless. And I also recommend using IDE for a production app.
The final source code is published here.
Step 1: Download gradle from https://gradle.org/releases/.
Step 2: Create settings.gradle
with:
rootProject.name = 'reactNativeBoilerplate'
Step 3: Run gradle wrapper
. This script will generate the following file and directories:
gradle/
gralew
gradlew.bat
Step 4: Modify settings.gradle
:
rootProject.name = 'reactNativeBoilerplate'
include ':app'
Step 5: Create the following files:
.gitignore
:
.gradle/
.DS_Store
build/
local.properties
build.gradle
:
buildscript {
ext {
buildToolsVersion = "29.0.3"
minSdkVersion = 21
compileSdkVersion = 29
targetSdkVersion = 29
ndkVersion = "20.1.5948944"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:4.1.0")
}
}
allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
maven { url 'https://www.jitpack.io' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
app/build.gralde
:
apply plugin: 'com.android.application'
import com.android.build.OutputFile
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
android {
compileSdkVersion 25
defaultConfig {
applicationId "com.transang.reactNativeBoilerplate"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:appcompat-v7:25.3.1'
}
app/proguard-rules.pro
:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
app/src/main/res/values/styles.xml
:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:textColor">#000000</item>
</style>
</resources>
app/src/main/AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.transang.reactNativeBoilerplate">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="@string/app_name"
android:allowBackup="false"
android:theme="@style/AppTheme"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
app/src/main/res/values/strings.xml
:
<resources>
<string name="app_name">React Native Boilerplate</string>
</resources>
app/src/main/java/com/transang/reactNativeBoilerplate/MainActivity.java
:
package com.transang.reactNativeBoilerplate;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
app/src/main/res/layout/activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Step 6: Build the application with ./gradlew build
.
> Task :app:lint
Execution optimizations have been disabled for task ':app:lint' to ensure correctness due to the following reasons:
- Type 'com.android.build.gradle.tasks.LintGlobalTask' property 'allInputs' cannot be resolved: Cannot convert the provided notation to a File or URI: constraint-layout-1.1.2.aar (com.android.support.constraint:constraint-layout:1.1.2). The following types/formats are supported: - A String or CharSequence path, for example 'src/main/java' or '/usr/include'. - A String or CharSequence URI, for example 'file:/usr/include'. - A File instance. - A Path instance. - A Directory instance. - A RegularFile instance. - A URI or URL instance. - A TextResource instance. Reason: An input file collection couldn't be resolved, making it impossible to determine task inputs. Please refer to https://docs.gradle.org/7.0.1/userguide/validation_problems.html#unresolvable_input for more details about this problem.
Ran lint on variant debug: 3 issues found
Ran lint on variant release: 3 issues found
Wrote HTML report to file:///home/transang/react-native-boilderplate/android/app/build/reports/lint-results.html
Wrote XML report to file:///home/transang/react-native-boilderplate/android/app/build/reports/lint-results.xml
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/7.0.1/userguide/command_line_interface.html#sec:command_line_warnings
Execution optimizations have been disabled for 1 invalid unit(s) of work during this build to ensure correctness.
Please consult deprecation warnings for more details.
BUILD SUCCESSFUL in 1s
55 actionable tasks: 13 executed, 42 up-to-date
This command will generate a directory app/build
with the apk files at app/build/outputs/apk/{debug,release}
.
Step 7: Install the app with ./gradlew installDebug
.
Step 8: Now, you can open the app from the device or emulator.