This is an Android app template which can be used for new projects. A small example app is available here.
Check out AndroidAppUtil for several utility classes.
- Technologies
- Setup
- App structure
- Predefined Modules
- Module/Package structure
- Testing
- Other
- Recommended Reading
- License
- Kotlin
- AndroidX Jetpack
- AAC Navigation for in-app navigation
- ViewBinding
- Koin for dependency injection
- Retrofit/OkHttp/Gson for networking
- Reaktor (MVI) as architectural pattern
- (Room for local data storage)
- Create your git repository and check it out on your machine.
- Add
git@github.com:tailoredmedia/AndroidAppTemplate.git
as remote and merge the latest commit into your repository (you most likely need to--allow-unrelated-histories
). - Run the provided
setup.sh
script to rename files and properties according to project. Afterwards deletesetup.sh
from your repository.setup.sh
script needs bash version 4+. MacOS has bash version 3.2 pre-installed and needs to be upgraded! - Change
README.md
content to something appropriate. - Commit and Push to your git repository.
Features should be contained in a separate module. The core
module should contain shared code, for example api or database classes that are needed in multiple feature modules. The app
module contains Android app related (ui) code. Depending on the project size
-
each feature could be contained in a separated module to support and promote reusability, such as for example a
login
module or amap
module. Each module then contains all the necessary code for the module to live on its own. For example alogin
module could contain the login api, the token storage database and the views containing the login user interface. -
or all ui related elements are located in the
app
module in the according feature packages and thecore
module contains business logic that can potentially be shared with other feature or ui modules in future expansions of the application.
Remember however: app and module structure should be thought through separately for every project.
Despite you and your brain being the judge of how the project should best be structured, at least three modules should be present:
core
: A base Kotlin or Android module containing reusable (business logic) code; such as Api, Database or Repos.base-ui
: A base Android module containing reusable UI components.app
: An Android module containing the application.
When creating new modules, you should probably use (apply) one of the predefined library-module gradle files: gradle/library-module-android.gradle
or gradle/library-module.gradle
.
- Model classes should be located in a
model
package. - Network related classes and interfaces (e.g. networking api's) are located in a
remote
package. - Local storage related classes (e.g. databases or dao's) are located in a
local
package. - Classes that do not correspond to a certain feature, should either be located in an
all
package, anutil
package or at the top level of the module.
These rules can be applied to either whole modules or packages depending on if you have feature modules or feature packages. An example for such a module/package structure can be found here.
Every module should contain tests for its use cases:
test
: Write unit tests for everyViewModel
orService
/Repository
. Mockito or PowerMock can be used to mock objects and verify correct behaviour.androidTest
: Write UI tests for common actions in your app. Use JUnit 4 Tests with Espresso. Some helper methods are available in EspressoUtils.
The dependencies for testing are located in the gradle/test-dependencies-android.gradle
and gradle/test-dependencies.gradle
files. If your module
already implements gradle/library-module-android.gradle
or gradle/library-module.gradle
, then these dependencies are automatically added to the module
.
If your module does not implement these standard library gradle files, add the test dependencies with:
apply from: rootProject.file("gradle/XXX.gradle")
All dependencies are located in the Libs.kt
file in the buildSrc
folder. To implement them use implementation Libs.XXX
.
Checking whether dependencies are ready to be updated, use ./gradlew refreshVersions
. Afterwards the newer version is added as comments to the versions.properties
file. Look here for the refreshVersions
gradle plugin that is used for that.
If you want to add a new dependency, add it to the module's build.gradle
as you would normally:
def room_version = "1.0.0"
implementation "androidx.room:room-runtime:$room_version"
Afterwards execute ./gradlew buildSrcVersions
. This task then extracts the dependency, adds it to Libs.kt
, adds its version to versions.properties
and automatically adds any updates next to the version if there is any.
Do not add your dependency manually to Libs.kt
- this works but is discouraged.
After the plugin has added your dependency to the Libs.kt
file, replace the lines in your build.gradle
:
implementation(Libs.room_runtime)
ktlint is a Kotlin linter and formatter. Using it is required to keep the code base clean and readable.
Use ./gradlew ktlintCheck
to lint your code.
To conform to the rules either:
- configure AndroidStudio accordingly.
- use
./gradlew ktlintApplyToIdea
to overwrite IDE style files. Read more here.
The goal of these conventions is to reduce the effort needed to read and understand code and also enable reviews to focus on more important issues than arguing over syntax.
Bold rules should be applied. Italic rules are optional.
Component | Rule | Example |
---|---|---|
Layouts | <what>_<where>.xml | activity_main.xml , item_detail.xml |
Sub-Layouts | <what>_<where>_<description>.xml | activity_main_appbar.xml |
Strings | <where>_<what>_<description> | detail_tv_location |
Drawables | <what>_<where>_<description> | btn_detail_background , card_overview_background |
Icons | ic_<description>_<where>.xml | ic_close.xml , ic_location_pin_detail.xml |
Dimensions | <where>_<what>_<description>_<size> | margin , detail_height_card , textsize_small |
Styles | <What>.<Description> | Text.Bold , Ratingbar.Preview |
Component Ids | <what><Description> | btnOpen , tvTitle |
- Kotlin
- Kotlin Coroutines
- Kotlin Flow
- Navigation Architecture Component
- ViewBinding
- control
- Koin
- Retrofit
- Room
Copyright 2020 Tailored Media GmbH.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.