Android Kotlin/Java Code Guidelines
Please read the following chapters before jumping in
- Coding language
- Supported Android Versions
- Gradle
- Code style
- App architecture
- Recommended libraries and frameworks
- Automated tests
- Git
- Code reviews
- Staging and production deployment
- Android Studio
- Books and resources
Coding language
Our language of choice is Kotlin for all new Android application. An exception are existing projects written in Java.
Supported Android versions
Minimum Supported Version
unless otherwise specified the minimum supported version should be API version 19 (KitKat) or API version 21 (Lollipop)Compile Sdk Version
always use the latest versionTarget Sdk Version
always use the latest version
Gradle
All new projects should use Gradle’s Kotlin DSL. An exception are existing projects written in Groovy DSL. All configurations, library versions, ect. should be kept in the buildSrc module.
Here are a few handy snippets:
object ProjectVersions {
private const val versionMajor = 1
private const val versionMinor = 0
private const val versionPatch = 0
private const val versionBuild = 0
const val versionCode = versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
const val versionName = "$versionMajor.$versionMinor.$versionPatch.$versionBuild"
const val archivesBaseName = "[NameOfProject]-$versionName"
}
Always include links above versions
//https://mvnrepository.com/artifact/androidx.test.ext/junit
const val androidJUnitVersion = "1.1.1"
Explain beta version inclusion under link
//https://developer.android.com/jetpack/androidx/releases/constraintlayout
//[ConstraintLayout 2.0.0-beta1] NPE when calling MotionLayout.transitionToState https://issuetracker.google.com/issues?q=132473209
const val constraintLayoutVersion = "2.0.0-beta3"
Code style
Follow the Official Kotlin Style Guide and Android Kotlin style guide.
Follow the Google Java Style Guide for Java code formatting.
Enable the following options in Android Studio’s before commit portion of the commit dialog:
Best practices
- Use
DromedaryCase
for: classes, styles - Use
camelCase
for: method names, variables - Use
snake_case
for: Classes, AndroidStyles - Use
SCREAMING_SNAKE_CASE
for: constant variables, enum constants - Use braces even when the body is empty or contains only a single statement!
- Use project-wide 2 space indentations
- Write self-documenting code
- A method should do what its name entails and nothing more
- Each top-level class resides in a source file of its own
- Try hard to keep classes under 500 lines of code
- Classes and methods should be cohesively grouped and composed
Automatic code formatting & checks
To automate checking that the code follows the guidelines and code formatting use ktlint - a Kotlin linter with a smart default rules matching the official Kotlin code style.
Ktlint Gradle plugin provides the following Gradle tasks (among others):
ktlintCheck
- checks all SourceSets and project Kotlin script files,ktlintFormat
- tries to format according to the code style all SourceSets Kotlin files and project Kotlin script files.
App architecture
All new applications should adopt Model View ViewModel (MVVM) architecture pattern, leveraging Android Architecture Components. See Google’s recommended app architecture for reference.
The recommended stack for Kotlin is:
- Hilt/Koin (Dagger)
- Retrofit
- Room
- RxJava/Coroutines
- ViewModels with LiveData/StateFlow
- Data Binding (optional)
- Navigation library (optional)
Any differences should be discussed with the project’s tech lead.
Project structure
Package by Feature motivation
com/app/
activity
BaseActivity.kt
fragment
BaseFragment.kt
useCase
BaseUseCase.kt
database
AppDatabase.kt
login
LoginFragment.kt
LoginViewModel.kt
LoginService.kt
LoginDataClass.kt
user
UserRepository.kt
UserRemoteDataSouce.kt
UserLocalDataSource.kt
UserService.kt
UserDao.kt
UserModel.kt
userList
UserListFragment.kt
UserListViewModel.kt
UserListUseCase.kt
UserListWorker.kt
UserListModel.kt
userDetails
UserDetailsFragment.kt
UserDetailsViewModel.kt
UserDetailsUseCase.kt
UserDetailsModel.kt
- Classes that change together are packaged together.
- Classes that are used together are packaged together.
- Avoid package such names base, data, model, api, ect., except for cases were your extending a class eg . activity/BaseActivity.kt
- Nested packages should only be referenced by their direct parents
Styles
- android:layout_** or app:layout_** should be defined in xml
- use android:textAppearance for styling text
- extract and reuse common dimensions
- extract and reuse common styles
- a style should always reference its parent style
- split large style files in to multiple smaller files styles_user_list.xml, styles_user_details.xml, ect.
- don’t use hardcoded color values (#FFFFFF), reference color resources instead (@color/white) to support themes
- colors.xml should contain only colors by name
<color name="white">#FFFFFF</color>
good<color name="button_text">#FFFFFF</color>
bad
- create a separate strings_constants.xml for storing non translatable strings
Localization
- Every project should have it’s own google Sheet named like
<ProjectName> - Localization
. Please ask your PM or lead developer to create one and give you read/write access. - Create the following Gemfile in project root: ```ruby source “https://rubygems.org”
gem ‘babelish’ gem ‘google-api-client’ gem ‘activesupport’
3. Create folder named `Localize` and copy files from [sample](/code-guidelines/android/resources/localization_scripts.zip) zip file
4. Look for further instructions in `Localize/README.txt`
#### App configuration
Use Android productFlavors as well as buildTypes for app configuration across dev/staging/production.
Always include a signing config for debug and commit the debug.keystore to version control.
signingConfigs { getByName(“debug”) { storeFile = file(“debug.keystore”) storePassword = “android” keyAlias = “androiddebugkey” keyPassword = “android” } } ```
Recommended libraries and frameworks
The basic idea is to encourage you to use popular, top rated and evolving libraries only. Allways consider if one of Jetpack’s libraries will solve your issue before considering external sources. If you need access to any of the mentioned services, check who is responsible for that service on Vendors & Administrators and contact them.
DO NOT
- use libraries with low star rating or ones that are outdated/deprecated
- install libraries by copying source code into the project
- install libraries with jar/aar files if it’s possible to compile it as a dependency in the module’s build.gradle file
List of libraries you should consider using:
Networking and data manipulation
- Retrofit* - Networking client
- OkHttp* - HTTP client
- Room* - Mobile database
- Gson Converter - Json/object converter
User Inteface
- Awesome Android UI - List of UI libraries
- Jetpack Compose - Android’s toolkit for building UI
Utilities
- Coroutines* - Asynchronous programming in Kotlin
- RxJava 2* - Reactive Extensions for Java
- RxAndroid* - Reactive Extensions for Android
- Hilt* - Dependency injection framework based on Dagger
- Koin* - Dependency injection framework
- Dagger 2.0 - Dependency injection framework
- Glide* - Image loading/caching library focused on smooth scrolling
- Picasso* - Lightweight image loading/caching library
- Timber - Logging utility library
- LeakCanary - Memory leak detection library
- Stetho - Debug Bridge for Android apps
Testing
- Mockk* - Mocking library aimed at kotlin
- Espresso* - UI testing
- Mockito* - Mocking framework for unit tests
- Robolectric - Run instrumented tests without an emulator
- PowerMock - Testing framework extension for mocking static/final/etc.
- Android-Arch* - See test helpers for various components
* If you are not familiar with this library, get familiar with it ASAP (you should know all of the libraries from the list but these are a must).
List of services you should consider using:
- Fabric & Crashlytics - Beta distribution and crash reporting
- Facebook - Facebook related operations
- Google analytics - Google analytics
Automated tests
We should strive towards practicing TDD.
The developer should make a conscious effort to write tests early and often. Every feature should have backing tests before pushing it to git. The developer should locally run all Unit test related to the story and verify they pass before pushing.
Features should have mostly unit tests, but also a smaller number of end-to-end test for user flows or whole screens and sometimes integration tests to check integration between two or more units.
For a detailed guide, check the Android documentation.
The developer can rely on CI to run the full test suite. Use circle.yml (wip) as a starting point for CircleCI configuration.
Development tools
Tools for display and control of connected Android devices. Useful for sharing the device screen for pairing or live demos.
- scrcpy - For devices connected via USB (wireless connection only for paid version).
- Vysor - For devices connected via USB or over TCP/IP.
Performance
- General
- Additional performance tips
-
Gpu rendering Android includes some on-device developer options that help you visualize where your app might be running into issues rendering its UI, such as performing more rendering work than necessary or executing long thread and GPU operations.
E.g., If the layout has a white background, children don’t need to have the same color; otherwise, it’s just an additional cost for the GPU. You might not notice this in some simple layout hierarchies, but in some complex RecyclerView layouts where it is necessary to provide smooth UX, these optimizations could help us achieve better FPS.
Security and optimizations
Git
The Git guidelines are a part of the general guidelines. Be sure to read them as well.
Code reviews
Keep the branches as small and relevant as possible to avoid huge PRs. Each project will have a lead developer on it, he will review the code before merging/squashing it to the base branch.
Staging and production deployment
Leverage Play Console’s Internal test track
and Closed track - Alpha
for distributing build previews.
Android Studio
Android Studio is something you are using daily and it is one of your main tools. You should not only be comfortable using it but be fast and efficient as well. You should create a cozy and familiar environment:
- use a theme that is easy on the eyes (we recommend the Darcula theme)
- use a font that works well with code (we recommend Inconsolata with straight quotes)
- get to know the shortcuts (and modify/add them if needed)
- set up and use live templates
- research popular and useful plugins and use them
- research useful actions/settings and use them
Useful Android Studio shortcuts
Knowing the shortcuts for actions that you repeat often is paramount. It will save you a lot of time and will streamline your development process. There are two categories of shortcuts you should be using:
- Shortcuts for actions that you do often (use the Key Promoter plugin).
- Shortcuts for actions that you do not use but should (take a look at the list below for some examples).
List of some useful shortcuts:
- Generate code: CMD + N
-
Refactor: SHIFT + F6
- Recent files: CMD + E
- Navigate to class: CMD + O
- Find action: SHIFT + CMD + A
-
Search everywhere: SHIFT, SHIFT
- Jump to delaration: CMD + B
- Jump to implementation: ALT + CMD + B
-
Find usages: ALT + F7
- Move statement up/down: SHIFT + CMD + up/down arrow
- Toggle comment: CMD + /
- Show quick fix: ALT + ENTER
- Toggle column selection mode: Shift + Alt + Insert
- Reformat code: CMD + Alt + L
- Optimize imports: CMD + Alt + O
Books and resources
Java
- The Busy Coder’s Guide to Android Development - Comprehensive book about Android, Android Studio and more
- Effective Java - Book with java best practices
- Material icons - Collection of material icons
- Codepath Guides - This not enough for you? Codepath Guides offer more than you ever wanted to know about Android-related things
- Android Architecture Blueprints - This project implements the same app using different architectural concepts and tools.
- ViewModels and LiveData: Patterns + AntiPatterns