Kotlin has been officially announced by Google as a first-class programming language for Android. Find out why Kotlin is the best tool available for you as a newcomer and why senior Android developers first adopted Kotlin.
In this chapter, you will learn how to set up a working environment. You will install and run Android Studio and set up Android SDK and Kotlin. Here, you will also be introduced to some important and useful tools such as Android Debug Bridge (adb).
Since you don't have your project yet, you will set it up. You will initialize a Git repository to track changes in your code and create an empty project. You will enable it to support Kotlin and add support for additional libraries that we will use.
After we have initialized the repository and project, we will go through the project structure and explain each file the IDE has generated. Finally, you will create your first screen and take a look at it.
This chapter will cover the following points:
- Setting up an environment for the development of Git and Gradle basics
- Working with Android Manifest
- Android emulator
- Android tools
Before we start our journey, we will answer the question from the chapter title--Why Kotlin? Kotlin is a new programming language developed by JetBrains, the company that developed IntelliJ IDEA. Kotlin is concise and understandable, and it compiles everything to bytecode just like Java. It can also compile to JavaScript or native!
Kotlin comes from professionals of the industry and solves problems programmers are facing every day. It is easy to start and adopt! IntelliJ comes with a Java to Kotlin converter tool. You can convert Java code file by file and everything will still work flawlessly.
It is interoperable and can use any existing Java Framework or library. The interoperability is impeccable and does not require wrappers or adapter layers. Kotlin supports build systems such as Gradle, Maven, Kobalt, Ant, and Griffon with external support.
The most important thing about Kotlin, for us, is that it works perfectly with Android.
Some of the most impressive Kotlin features are as follows:
- Null safety
- Exceptions are unchecked
- Type inference works everywhere
- One-liner functions take one line
- Generated getters and setter out of the box
- We can define functions outside of classes
- Data classes
- Functional programming support
- Extension functions
- Kotlin uses Markdown instead of HTML for API documents! The Dokka tool, a Javadoc alternative, can read Kotlin and Java source code and generate combined docs
- Kotlin has a better generics support than Java
- Reliable and performant concurrent programming
- String patterns
- Named method arguments
On May 17th 2017, Google announced that it's making Kotlin, a statically typed programming language for the Java Virtual Machine, a first-class language to write Android apps.
The next version of Android Studio (3.0, current one is 2.3.3) will support Kotlin out of the box. Google will put its effort in the future of Kotlin.
To develop our application, we will need some tools. First of all, we will need an IDE. For that purpose, we will use Android Studio. Android Studio provides the fastest tools to build apps on every type of Android device.
Android Studio offers professional code editing, debugging, and performance tooling. It's a flexible build system that allows you to focus on building a top quality application.
Setting up Android Studio takes just a few clicks. Before we go any further, you need to download the following version for your operating system:
https://developer.android.com/studio/index.html
Here are the instructions for macOS, Linux, and Windows:
macOS: To install it on macOS, follow these steps:
- Launch the Android Studio
DMG
file. - Drag and drop Android Studio into the
Applications
folder. - Launch Android Studio.
- Select whether you want to import previous Android Studio settings.
- Click on
OK
. - Follow the instructions until Android Studio is ready for use.
Linux:To install it on Linux, follow these steps:
- Unpack the archive you downloaded to an appropriate location for your applications.
- Navigate to
bin/directory/
. - Execute
/studio.sh
. - Select whether you want to import previous Android Studio settings or not.
- Click on
OK
. - Follow the instructions until Android Studio is ready for use.
- Optionally, select
Tools
|Create Desktop Entry
from the menu bar.
Note
If you are running a 64-bit version of Ubuntu, you need to install some 32-bit libraries with the following command:sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386
In case you are running a 64-bit Fedora, the command is follows:sudo yum install zlib.i686 ncurses-libs.i686 bzip2-libs.i686
Windows:To install it on Windows, follow these steps:
- Execute the
.exe
file you downloaded. - Follow the instructions until Android Studio is ready for use.
Android SDK comes with emulators capable of running applications we develop. We will need it for our project! The purpose of an emulator is to simulate a device and displays all its activity windowed on your computer. What can we do with it? We can prototype, develop, and test--all this without a hardware device. You can emulate phones, tablets, wearables, and TV devices. You can create your own device definitions, or you can use predefined emulators.
The good thing about emulators is that they are fast. In many situations, it will take less time to run an application on an emulator instance than on a real hardware device.
Working with the emulators is just as easy with a real hardware device. For gestures, you use your mouse, and for input, your keyboard.
Emulators can do anything a real phone does! You can easily send incoming phone calls and text messages! You can specify the location of the device, send fingerprint scans, adjust network speed and status, or even simulate battery properties. Emulators can have a virtual SD card and internal data storage, both of them you can use to send real files to that space.
Android Virtual Device (AVD) configuration is used to define an emulator. Each AVD instance works as a completely independent device! For the purpose of creating and management of AVDs, we use the AVD Manager. An AVD definition holds a hardware profile, system image, storage area, skin, and other important properties.
Let's play with it! To run the AVD Manager, do one of the following:
Select Tools | Android | AVDManager or click on the AVDManager icon in the toolbar:

It displays all AVDs you've already defined. As you can see, we don't have any yet!
What can we do here? We can do the following:
- Create a new AVD
- Edit an existing AVD
- Delete the existing AVD
- Create hardware profiles
- Edit an existing hardware profile
- Delete an existing hardware profile
- Import/export definitions
- Start or stop the AVD
- Clear data and reset the AVD
- Access the AVD
.ini
and.img
files on the filesystem - View the AVD configuration details
To obtain the AVD instance, you can either create a new AVD from the beginning or duplicate an existing AVD and modify it by need.
From the Your Virtual Devices of the AVD Manager, click on Create
Virtual
Device
(you can do the same as you run your app from within Android Studio by clicking on the Run
icon, and then, in the Select Deployment Target
dialog, choose Create
New
Emulator
). Please refer to the following screenshot:

Select a hardware profile and then click on Next
, as shown in the previous screenshot.

If you notice the Download
link next to the system image, you have to click on it. The download process starts, as you can see in the following screenshot:

We must note that the API level of the target device is very important! Your application can't run on a system image whose API level is less than the one required by your application. That attribute is specified in your Gradle configuration. We will deal with Gradle in detail later.
Finally, Verify Configuration
appears:

Change the AVD properties if needed and then click on Finish
to complete the wizard. The newly created AVD appears in the Your Virtual Devices
list or the Select Deployment Target
dialog, depending on where you accessed the wizard from.

If you need to create a copy of the existing AVD, follow these instructions:
- Open AVD Manager, right-click on the AVD instance, and select
Duplicate
. - Follow the wizard, and, after you modified what you needed, click on
Finish
. - A new modified version appears in our AVD list.
We will demonstrate dealing with hardware profiles by creating a new one from scratch. To create a new hardware profile, follow these instructions. In Select Hardware
, click on New Hardware Profile
. Please refer to the following screenshot:

Configure Hardware Profile
appears. Adjust the hardware profile
properties as needed. Click on Finish
. Your newly created hardware profile
appears.
If you need a hardware profile
based on an existing one, follow these instructions:
- Select an existing
hardware profile
and click onClone Device
. - Update the
hardware profile
properties by your needs. To complete the wizard, click onFinish
. - Your profile appears in the
hardware profile
list.
Let's go back to the AVD list. Here, you can perform the following operations on any existing AVD:
- Edit it by clicking on
Edit
- Delete by right-clicking and choosing
Delete
- Access the
.ini
and.img
files on the disk by right-clicking on an AVD instance and choosingShow on Disk
- To view the AVD configuration details, right-click on an AVD instance and choose
View
Details
Since we covered this, let's go back to the hardware profile
list. Here, we can do the following:
- Edit a hardware profile by selecting it and choosing
Edit Device
- Delete a hardware profile by right-clicking on it and choosing
Delete
Then, we can run or stop an emulator or clear its data as follows:
- To run an emulator that uses an AVD, double-click on the AVD or just choose
Launch
- To stop it, right-click on it and choose
Stop
- To clear the data for an emulator, and return it to the same state as when it was first defined, right-click on an AVD and choose
Wipe Data
We will continue our emulators' journey with the explanation of command-line features that you can use with *-
.
To start an emulator, use the emulator command. We will show you some basic command-line syntax to start a virtual device from a terminal:
emulator -avd avd_name [ {-option [value]} ... ]
Another command-line syntax is as follows:
emulator @avd_name [ {-option [value]} ... ]
Let's take a look at the following example:
$ /Users/vasic/Library/Android/sdk/tools/emulator -avd Nexus_5X_API_23 -netdelay none -netspeed full
You can specify startup options when you start the emulator; later, you can't set these options.
If you need a list of available AVDs, use this command:
emulator -list-avds
The result is a list of AVD names from the Android home directory. You can override the default home directory by setting the ANDROID_SDK_HOME
environment variable.
Stopping an emulator is simple--just close its window.
To access devices, you will use the adb
command executed from the terminal. We will take a look into the common cases.
Listing all devices:
adb devices
Console output:
List of devices attachedemulator-5554 attachedemulator-5555 attached
Obtaining shell access to device:
adb shell
Accessing a specific device instance:
adb -s emulator-5554 shell
Where -s
represents device source.
Copying a file from and to a device:
adb pull /sdcard/images ~/imagesadb push ~/images /sdcard/images
Uninstalling an application:
adb uninstall <package.name>
One of the greatest features of adb
is that you can access it through telnet. Use telnet localhost 5554
to connect to your emulator device. Terminate your session using the quit
or exit
command.
Let's play with adb
:
- Connect to device:
telnet localhost 5554
- Change the power level:
power status fullpower status charging
- Or simulate a call:
gsm call 223344556677
- Send an SMS:
sms send 223344556677 Android rocks
- Set geolocation:
geo fix 22 22
We will cover some other tools you will need in everyday Android development.
Let's start with the following:
adb dumpsys
: To get information about a system and running an application, use theadb dumpsys
command. To get a memory status, execute the following command--adb shell dumpsys meminfo <package.name>
.
Next important tool is as follows:
adb shell procrank
: Theadb shell procrank
lists all the applications for you in the order of their memory consumption. This command does not work on live devices; you connect only with emulators. For the same purpose, you can use--adb shell dumpsys meminfo
.- For battery consumption, you can use--
adb shell dumpsys batterystats
--charged<package-name>
. - Next important tool is Systrace. To analyze performance of your application by capturing and displaying execution times, you will use this command.
When you have problems with application glitches, Systrace tool comes as a powerful ally!
It does not work with Android SDK Tools less than 20! To use it, you must have Python installed and configured.
Let's try it!
To access it from UI, open Android Device Monitor in Android Studio and then choose Monitor
:

Sometimes, it can be easier to access it from the terminal (command line):
Note
The Systrace tool has different command-line options, depending on the Android version running on your device.
Let's take a look at some examples:
General usage:
$ python systrace.py [options] [category1] [category2] ... [categoryN]
- Android 4.3 and up:
$ python systrace.py --time=15 -o my_trace_001.html
sched gfx view wm
- Android 4.2 and lower options:
$ python systrace.py --set-tags gfx,view,wm$ adb shell stop$ adb shell start$ python systrace.py --disk --time=15 -o my_trace_001.html
The last important tool we want to present is sdkmanager
. It allows you to view, install, update, and uninstall packages for the Android SDK. It is located in android_sdk/tools/bin/
.
Let's take a look at some common examples of use:
Listing installed and available packages:
sdkmanager --list [options]
- Installing packages:
sdkmanager packages [options]
You can send packages you got from --list
command.
- Uninstalling:
sdkmanager --uninstall packages [options]
- Updating:
sdkmanager --update [options]
There are also some other tools you can use in Android, but we only showed the most important ones.
We have installed Android Studio and introduced ourselves to some important SDK tools. We also learned how to deal with emulated devices that will run our code. It is time to start working on our project. We will develop a small application for notes and todos. This is a tool that everybody needs. We will give it a name--Journaler
and it will be an application capable of creating notes and todos with reminders that will be synced to our backend.
First step in development is initializing a Git repository. Git will be our code versioning system. It is up to you to decide if you will use GitHub, BitBucket, or something else for a remote Git instance. Create your remote repository and keep its URL ready, along with your credentials. So, let's start!
Go into the directory containing the project:
Execute: git init .
The console output will be something like this:
Initialized empty Git repository in <directory_you_choose/.git>
We initialized the repo.
Let's add the first file--vi notes.txt
.
Populate notes.txt
with some content and save it.
Execute git add .
to add all of the relevant files.
- Then:
git commit -m "Journaler: First commit"
The console output will be something like this:
[master (root-commit) 5e98ea4] Journaler: First commit1 file changed, 1 insertion(+)create mode 100644 notes.txt
As you remember, you prepared your remote Git repository url
with credentials. Copy url
into a clipboard. Now, execute the following:
git remote add origin <repository_url>
This sets the new remote.
- Then:
git remote -v
This verifies the new remote URL.
- Finally, push everything we have to remote:
git push -u origin master
If you are asked for credentials, enter it and confirm by pressing Enter.
We initialized our code repository. It is time to create a project. Start Android Studio and choose the following:
Start a new Android Studio Project or File
| New
| New Project
.
Create New Project
and a window appears.
Fill the application information:

Then, click on Next
.
Check the Phone and Tablet
option, and then choose Android 5.0
as the minimum Android version as follows:

Click on Next
again.
Choose Add No Activity
and click on Finish
, as follows:

Wait until your project is created.
You will notice a message about Unregistered VCS root detected
. Click on add root
or go to Preferences
| Version Control
| , and then select our Git repository from the list and the click on then + icon, as shown in the following screenshot:

To confirm everything, click on Apply
and OK
.
Before committing and pushing, update your .gitignore
files. The purpose of the .gitignore
file is to allow you to ignore files, such as editor backup files, build products, or local configuration overrides that you never want to commit into a repository. Without matching the .gitignore
rules, these files will appear in the untracked files
section of the Git status output.
Open .gitignore
located in your project root
directory and edit it. To access it, expand Project by clicking on Project
on the left side of Android Studio, and then, from the drop-down menu, choose Project
, as shown in the following screenshot:

Let's add some lines:
.idea.gradlebuild/gradle*!gradle-plugins*gradle-app.setting!gradle-wrapper.jar.gradletasknamecachelocal.propertiesgen
Then, edit .gitignore
, which is located in the app
module directory:
*.class.mtj.tmp/*.jar*.war*.earhs_err_pid*.idea/*.DS_Store.idea/shelf/android.tests.dependencies/confluence/target/dependencies/dist/gh-pages/ideaSDK/android-studio/sdkouttmpworkspace.xml*.versionsBackup/idea/testData/debugger/tinyApp/classes*/jps-plugin/testData/kannotatorultimate/.DS_Storeultimate/.idea/shelfultimate/dependenciesultimate/ideaSDKultimate/outultimate/tmpultimate/workspace.xmlultimate/*.versionsBackup.idea/workspace.xml.idea/tasks.xml.idea/dataSources.ids.idea/dataSources.xml.idea/dataSources.local.xml.idea/sqlDataSources.xml.idea/dynamic.xml.idea/uiDesigner.xml.idea/gradle.xml.idea/libraries.idea/mongoSettings.xml*.iws/out/.idea_modules/atlassian-ide-plugin.xmlcom_crashlytics_export_strings.xmlcrashlytics.propertiescrashlytics-build.propertiesfabric.propertiestarget/pom.xml.tagpom.xml.releaseBackuppom.xml.versionsBackuppom.xml.nextrelease.propertiesdependency-reduced-pom.xmlbuildNumber.properties.mvn/timing.properties!/.mvn/wrapper/maven-wrapper.jarsamples/*build/*.gradle/*!libs/*.jar!Releases/*.jarcredentials*.gradlegen
You can use this .gitignore
configuration from the preceding. Now we can commit and push
cmd + 9 on macOS or ctrl + 9 on Windows/Linux (shortcut for View
| Tool Windows
| Version Control
). Expand unversioned files, select them, and right-click on Add
to VCS
.

Press Cmd + K (or Ctrl + K on Windows/Linux), check all files, enter commit
message, and, from the Commit
drop-down menu, choose Commit and Push
. If you get Line Separators Warning
, choose Fix and Commit
. The Push Commits
window will appear. Check Push Tags
and choose Current Branch
, and then Push
.
Gradle is a build system. You can build your Android application without one, but, in that case, you have to use several SDK tools by yourself. That is not simple! This is a part where you need a Gradle and Android Gradle plugin.
Gradle takes all the source files and processes them by tools we mentioned. Then, it packs everything into one compressed file with the .apk
extension. APK can be uncompressed. If you rename it by changing its extension to .zip
, you can extract the content.
Each build system uses its convention. The most important convention is about placing source code and assets in a proper directory with proper structure.
Gradle is a JVM-based build system, so that practically means that you can write your own script in Java, Groovy, Kotlin, and so on. Also, it's a plugin-based system and is easy to extend. One good example of it is Google's Android plugin. You probably noticed build.gradle
files in your project. They are all written in Groovy, so any Groovy code you write will be executed. We will define our Gradle scripts to automate a building process. Let's set up our building! Open settings.gradle
and take a look at it:
include ":App"
This directive tells Gradle that it will build a module named App
. The App
module is located in the app
directory of our project.
Now open build.gradle
from project root
and add the following lines:
buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.3' } } repositories { jcenter() mavenCentral() }
We defined that our build script will resolve its dependencies from JCenter and Maven Central repositories. The same repositories will be used to resolve project dependencies. Main dependencies are added to target each module we will have:
- Android Gradle plugin
- Kotlin Gradle plugin
After you updated the main build.gradle
configuration, open build.gradle
located in the App module
directory and add the following lines:
apply plugin: "com.android.application" apply plugin: "kotlin-android" apply plugin: "kotlin-android-extensions" android { compileSdkVersion 26 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.journaler" minSdkVersion 19 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard- android.txt'), 'proguard-rules.pro' } } sourceSets { main.java.srcDirs += 'src/main/kotlin' }} repositories { jcenter() mavenCentral() }dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3" compile 'com.android.support:design:26+' compile 'com.android.support:appcompat-v7:26+'}
The configurations we set enable Kotlin as a development language for our project and Gradle scripts as well. Then, it defines a minimal and target sdk version that an application requires. In our case, this is 19
as minimum and 26
as target. It is important to note that in the default configuration section, we set application ID and version parameters too. The dependencies section sets dependencies for Kotlin itself and some Android UI components that will be explained later.
Android Studio contains everything you need to build an application. It contains source code and assets. All directories are created by the wizard we used to create our project. To see it, open the Project
window on the left side of the IDE (click on View
| Tool
Windows
| Project
), as shown in the following screenshot:

A project module represents a collection of source files, assets, and build settings that divide projects into discrete functionality parts. The minimal number of modules
is one. There is no real limit on the maximal modules
number your project can have. Modules
can be built, tested, or debugged independently. As you saw, we defined the Journaler
project with only one module named app
.
To add a new module, following these steps:
Go to File
| New
| New
Module
.

It's possible to create the following modules
:
- Android Application Module represents a container for your application source code, resources, and settings. The default module name is
app
, like in our created example. Phone & Tablet Module
.Android Wear Module
.Glass Module
.Android TV module
.Library
module represents a container for reusable code--a library. The module can be used as a dependency in other application modules or imported into other projects. When it's built, the module has an AAR extension--Android Archive instead of having an APK extension.
The Create New Module
window offers the following options:
- Android Library: All types are supported in an Android project. The build result of this library is an Android Archiver (AAR).
- Java Library: Only supports pure Java. The build result of this library is a Java Archiver (JAR).
- Google Cloud Module: This defines a container for the Google Cloud backend code.
It is important to understand that Gradle refers to modules
as individual projects. If your application code depends on the code for the Android library called Logger then in build.config, you use must include the following directive:
dependencies { compile project(':logger') }
Let's navigate through the project structure. The default view Android Studio uses to display your project files is Android view. It doesn't represent the actual file hierarchy on disk. It hides certain files or directories that are not often used.
Android view presents the following:
- All the build-related configuration files
- All manifest files
- All other resource files in a single group
In each application, the module content is presented in these groups:
- Manifests and
AndroidManifest.xml
files. - Java and Kotlin source code for application and tests.
- The
res
and Android UI resources. - To see the real file structure of the project, choose
Project view
. To do this, click onAndroid view
and, from the drop-down menu, chooseProject
.
By doing this, you will see a lot more files and directories. The most important of them are as follows:
module-name/
: This is the name of the modulebuild/
: This holds build outputslibs/
: This holds private librariessrc/
: This holds all code and resource files for the module organized in the following subdirectories:main
: This holds themain
source set files--source code and resources shared by all build variants (we will explain build variants later)AndroidManifest.xml
: This defines the nature of our application and each of its componentsjava
: This holds the Java source codekotlin
: This holds the Kotlin source codejni
: This holds the native code using the Java Native Interface (JNI)gen
: This holds the Java files generated by Android Studiores
: This holds application resources, for example, drawable files, layout files, strings, and so onassets
: This holds files that should be compiled into an.apk
file with no modificationtest
: This holds the test source codebuild.gradle
: This is the module level build configurationbuild.gradle
: This is the project level build configuration
Choose File
| Project
Structure
to change settings for the project in the following screenshot:

It contains the following sections:
SDK Location
: This sets the location of the JDK, Android SDK, and Android NDK that your project usesProject
: This sets Gradle and Android Gradle plugin versionsModules
: This edits module-specific build configurations
The Modules
section is divided in the following tabs:
Properties
: This sets the versions of the SDK and build tools for module buildingSigning
: This sets the certificate for APK signingFlavors
: This defines flavors for the moduleBuild
Types
: This defines build types for the moduleDependencies
: This sets dependencies needed by the module
Please refer to the following screenshot:

We are approaching an important phase of our project--defining build variants for our application. Build variant stands for a unique version of an Android application.
They are unique because they override some of the application attributes or resources.
Each build variant is configured per module level.
Let's extend our build.gradle
! Put the following code in the android
section of the build.gradle
file:
android { ... buildTypes { debug { applicationIdSuffix ".dev" } staging { debuggable true applicationIdSuffix ".sta" } preproduction { applicationIdSuffix ".pre" } release {} } ... }
We defined the following buildTypes
for our application--debug
, release
, staging
, and preproduction
.
Product flavors are created in a similar way like buildTypes
. You need to add them to productFlavors
and configure the needed settings. The following code snippet demonstrates this:
android { ... defaultConfig {...} buildTypes {...} productFlavors { demo { applicationIdSuffix ".demo" versionNameSuffix "-demo" } complete { applicationIdSuffix ".complete" versionNameSuffix "-complete" } special { applicationIdSuffix ".special" versionNameSuffix "-special" } } }
After you create and configure your productFlavors
, click on Sync Now
in the notification bar.
You need to wait a while for the process to be done. Names for Build Variants
are formed by the <product-flavor><Build-Type>
convention. Here are some examples:
demoDebug demoRelease completeDebug completeRelease
You can change the build variant to the one that you want to build and run. Go to Build
, select Build
Variant
, and select completeDebug
from the drop-down menu.

The Main/source
set is shared between all build variants in your application. If you need to create a new source set, you can do that for certain build types, product flavors, and their combinations.
All source set files and directories must be organized in a specific way, similar to the Main/Source
set. Kotlin class files that are specific to your debug build type must be located in src/debug/kotlin/directory
.
In order to learn how to organize your files, open the terminal window (View
| Tool
Windows
| Terminal
) and execute the following command line:
./gradlew sourceSets
Take a look at the output carefully. The report is understandable and self-explanatory. Android Studio doesn't create the sourceSets
directories. It's a work that has to be done by you.
If desired, you can change the location where Gradle is looking for a source set using the sourceSets
block. Let's update our build configuration. We will update the following expected source code paths:
android { ... sourceSets { main { java.srcDirs = [ 'src/main/kotlin', 'src/common/kotlin', 'src/debug/kotlin', 'src/release/kotlin', 'src/staging/kotlin', 'src/preproduction/kotlin', 'src/debug/java', 'src/release/java', 'src/staging/java', 'src/preproduction/java', 'src/androidTest/java', 'src/androidTest/kotlin' ] ... }
Code and resources that you want packaged only with certain configurations, you can store in the sourceSets
directories. Here are given examples for build with the demoDebug
build variant; this build variant is a product of a demo
product flavor and debug
build type. In Gradle, the following priority is given to them:
src/demoDebug/ (build variant source set) src/debug/ (build type source set) src/demo/ (product flavor source set) src/main/ (main source set)
This is the priority order that Gradle uses during the build process and considers it when applying the following build rules:
- It compiles source code in the
java/
andkotlin/
directories together - It merges manifests together into a single manifest
- It merges files in the
values/
directories - It merges resources in the
res/
andasset/
directories
The lowest priority is given to resources and manifests included with library module dependencies.
We configured our build types and flavors, now we will need some third-party libraries. We will use and add support for Retrofit, OkHttp, and Gson. This is an explanation for each of them:
- Retrofit is a type-safe HTTP client for Android and Java by Square, Inc. Retrofit is one of the most popular HTTP client library for Android as a result of its simplicity and its great performance compared to the others.
OkHttp
is an HTTP client that's efficient by default--HTTP/2 support allows all requests to the same host to share a socket.- Gson is a Java library that can be used to convert Java objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including preexisting objects that you do not have a source code for.
There are a few open source projects that can convert Java objects to JSON. Later in this book, we will add Kotson to provide Gson bindings for Kotlin.
Let's extend build.gradle
with dependencies for Retrofit and Gson:
dependencies { ... compile 'com.google.code.gson:gson:2.8.0' compile 'com.squareup.retrofit2:retrofit:2.2.0' compile 'com.squareup.retrofit2:converter-gson:2.0.2' compile 'com.squareup.okhttp3:okhttp:3.6.0' compile 'com.squareup.okhttp3:logging-interceptor:3.6.0' ... }
After you updated your Gradle configuration, sync it again when asked!
Every application must have an AndroidManifest.xml
file and the file must have exactly that name. Its location is in its root
directory, and, in each module, it contains essential information about your application to the Android system. The manifest
file is responsible for defining the following:
- Naming a package for the application
- Describing the components of the application--activities (screens), services, broadcast receivers (messages), and content providers (database access)
- Permissions that application must have in order to access protected parts of the Android API
- Permissions that other applications must have in order to interact with the application's components, such as content providers
The following code snippet shows the general structure of the manifest
file and elements that it can contain:
<?xml version="1.0" encoding="utf-8"?> <manifest> <uses-permission /> <permission /> <permission-tree /> <permission-group /> <instrumentation /> <uses-sdk /> <uses-configuration /> <uses-feature /> <supports-screens /> <compatible-screens /> <supports-gl-texture /> <application> <activity> <intent-filter> <action /> <category /> <data /> </intent-filter> <meta-data /> </activity> <activity-alias> <intent-filter> . . . </intent-filter> <meta-data /> </activity-alias> <service> <intent-filter> . . . </intent-filter> <meta-data/> </service> <receiver> <intent-filter> . . . </intent-filter> <meta-data /> </receiver> <provider> <grant-uri-permission /> <meta-data /> <path-permission /> </provider> <uses-library /> </application> </manifest>
Each Android application defines its main Application
class. The Application
class in Android is the base class within an Android application that contains all other components, such as activities
and services
. The Application
class, or any subclass of the Application
class, is instantiated before any other class when the process for your application/package is created.
We will create an Application
class for Journaler. Locate the main sources directory. Expand it, and if there is no Kotlin sources directory, create it. Then, create the package com
and subpackage journaler; to do so, right-click on the Kotlin directory and choose New | Package. Once you've created the package structure, right-click on the journaler package and choose New
| Kotlin
File
/Class
. Name it Journaler
. Journaler.kt
is created.
Each Application
class must extend the Android Application class as shown in our example:
package com.journaler import android.app.Application import android.content.Context class Journaler : Application() { companion object { var ctx: Context? = null } override fun onCreate() { super.onCreate() ctx = applicationContext } }
For now, our main Application
class will provide us with static access to application context. What this context is will be explained later. However, Android will not use this class until it's mentioned in manifest. Open the app
module android manifest
and add the following block of code:
<manifest xmlns:android="http://schemas.android.com/apk/ res/android" package="com.journaler"> <application android:name=".Journaler" android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> </application> </manifest>
With android:name=".Journaler"
, we tell Android which class to use.
We created an application with no screens. We will not waste time, we will create one! Create a new package named activity
where all our screen classes will be defined, and create your first Activity
class named MainActivity.kt
. We will start with one simple class:
package com.journaler.activity import android.os.Bundle import android.os.PersistableBundle import android.support.v7.app.AppCompatActivity import com.journaler.R class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) setContentView(R.layout.activity_main) } }
Soon, we will explain the meaning of all these lines. For now, it's important to note that setContentView(R.layout.activity_main)
assigns UI resource to our screen and activity_main
is a name of the XML defining it. Since we don't have it yet, we will create it. Locate res
directory under the main
directory. If there is no layout folder there, create one and then create a new layout named activity_main
by right-clicking on layout
directory and choosing the New
| Layout
resource file. Assign activity_main
as its name and LinearLayout
as its root element. The content of the file should be similar to this:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/ apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> </LinearLayout>
There is one more thing to do before we are ready to run our application: we must tell our manifest about this screen. Open the main manifest
file and add the following piece of code:
<application ... > <activity android:name=".activity.MainActivity" android:configChanges="orientation" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
We will explain all these attributes soon; all you need to know for now is that your application is ready to run. However, before that, commit and push
your work. You don't want to lose it!
In this chapter, we introduced the basics of Android and gave glimpses of Kotlin. We configured a working environment and made the first screen of our application.
In the next chapter, we will go deeper into the matter of Android. You will learn how to build your application and customize different variants. We will also cover different ways of running the application.