Android Guidelines
Setting up a new project
Server Side
While following every step mentioned in git here, there is a small additional step you need to follow:
In bitbucket go to Settings->PULL REQUESTS->Default description
and paste the following content:
## Description
### Why was this change necessary?
[text here]
### How does it address the problem?
[text here]
### Are there any side effects?
[text here]
### Do you want any specific feedback?
[text here]
### Do you have resources that will help the reviewer?
[MP-](https://grappus.atlassian.net/browse/MP-)
### Zeplin screen design links?
[link here]
### Did you run `./gradlew spotlessApply; ./gradlew testDebugUnitTestCoverage;` locally?
[yes/no]
Client Side
Setting up a new project takes up a lot of effort and forgetting up some edge cases is pretty normal which may lead to some fatal errors which can lead to some serious issues to be handled later.
We have done this job for you. Follow along to see the process.
- Clone our base project from here.
-
Change the required package name. While working with multiple modules few things to keep in mind with the modules package name. For example, take
com.android
as the base package name:(i) The package name of the
app module
should becom.android
.(ii) Package name of
api module
should becom.android.api
.(iii) Package name of
core module
should becom.android.core
.(iv) Package name of
logic module
should becom.android.logic
.(v) Ensure that application id in
manifest.xml
andbuild.gradle
is the same.Naming the packages in this format helps in running test cases with Jacoco.
-
Change the API response structure according to your needs in this file and amend it's test class accordingly in your local project.
- Format the code by running
./gradlew spotlessApply
command and run tests by running./gradlew testDebugUnitTestCoverage
. - If the above command fails, ensure that you are on
java version 1.8
and if not please upgrade or degrade your java version. Degrading java version can be done by runningexport JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
in terminal. More details here. - Delete the
.git
folder in your project's root directory. - Rename your root project name.
- Connect your local repo to a remote source.
if all the above points run successfully and your build is successful then you are ready to roll.
Creating Git Aliases
Aliases are used to create shorter commands that map to longer commands. Here are a few handy git aliases you can make to avoid copy and pasting a command again and again.
alias prcheck="./gradlew spotlessApply; ./gradlew spotlessCheck testDebugUnitTestCoverage;sapply"
: Add this to your bash profile and you can runprcheck
in your directory to assert things are fine before submitting a PR.
Before you start developing
Set up File template in Intellij
We have made an Android studio template to create files required for a fragment and it's related files.
- Download the File template from here and follow the instructions written in
Readme.txt
inside the newly extracted folder. - Navigate to Android Studio and go to
File-> Import Settings...
and select the settings.zip inside the newly-downloaded file template. - After completing the above processes restart Androids studio and you should see file template as seen in the image in the above-downloaded folder.
While Developing
Few things to remember while developing so that we all can be on the same page.
Architecture:
We are following a mixture of MVI and MVVM architecture in this project with kotlin as the primary language for development. In this project, we heavily use RxJava, RxKotlin and Live Data for managing asynchronous call in API and database. We manage our dependencies using dagger, code test coverage is maintained using Jacoco and mocking of objects including API response is done using mockito.
We strictly follow the Single responsibility principle and therefore this project is divided into 6 modules.
-
core: This module contains all the view model base classes, models for app views and Transport classes for transporting server entities to app models.
-
logic: Logic contains all the view model implementations and App logic. Dagger modules are also defined here only.
-
app: App is the view layer and contains all the views implementation. It also contains dagger components.
-
api: Api layer contains the network related implementations.
-
buildSrc It manages external dependencies for the whole project.
-
local-resources This module is used to hold static JSON responses which can be used for local build-types and testing purposes.
Nomenclature :
Typacilly each fragment contains 5 Files.
* Fragment: The part where UI events are handled.
* FragmentBindingModel: The part where UI events processing is done and formatted details
are sent to the fragment.
* FragmentViewModel: Here the events are processed. It contains all the required data to
maintain the state of the fragment.
* FragmentHandler: It is an interface where we declare the click listeners of UI events.
* FragmentLayout: It contains the UI design code.
The naming convention of all files should be as described above just replace the above word Fragment with your desired name.
Testcases:
Write the test cases of logic module religiously by covering each ViewEvent including api and database calls by asserting their expected and actual view state update before and after the operation. We strictly maintain a minimum of 70% code coverage in our test cases which include branch testing (there should be an if for every else) and instructions testing.
Any PR which does not satisfy the minimum test coverage criteria shall not be merged. To see your current coverage:
- Run
./gradlew testDebugUnitTestCoverage
in your terminal. - Navigate to the logic module in the Project view in AS.
- Go to
build->reports->jacaco->testDebugUnitTestCoverage->html
and openindex.html
in your browser to see your test code coverage to every file in logic module.
Extension functions/properties
Kotlin provides the ability to extend a class with new functionality without having to inherit from the class, this is done via special declarations called extensions. We encourage you to write extension functions, primarily in the logic module and writing its test cases vigorously. Here is a small implementation of Datatype Extensions for your reference and it's test cases are written here.
Writing comments
No need to clutter your code by writing comments for every method but do not forget to write comments whenever you are performing some ad-hoc logic calculation. Do not use random numbers in that method, give them a proper variable name.
Use Vector Assets
Android Studio includes a tool called Vector Asset Studio that helps you add material icons and import Scalable Vector Graphic (SVG) and Adobe Photoshop Document (PSD) files into your project as vector drawable resources. Using vector drawables instead of bitmaps reduces the size of your APK because the same file can be resized for different screen densities without loss of image quality. For older versions of Android that don't support vector drawables, Vector Asset Studio can, at build time, turn your vector drawables into different bitmap sizes for each screen density. You can read more about it here.
Making reusable layouts:
Make the layout's reusable by using <include>
tag in the layout and pass data to them using data binding.
Avoid hard coding:
Do not hard code strings in the project. Use them via strings.xml
to ease the process of translation in different languages.
Using Kotlin only features:
We encourage you to use kotlin only features such as sealed classes, extension function, Objects, etc.
As said above we heavily use Scope Functions to write clutter-free code and avoid writing the same thing again and again. Please refer to the above link to read more about it.
Raising a PR
- Follow the steps as described in git section.
- Run
prcheck
alias in the terminal. - If you have made changes only in a single module, squash all your commits into 1 commit.
- If you have made changes in more than 1 module, please divide your PR into 3 commits i.e data, logic and UI. Following is an example commit message where each commit contains its relevant files.
feat(ALT-33): Adds sign in via OTP screen (data). feat(ALT-33): Adds sign in via OTP screen (logic). feat(ALT-33): Adds sign in via OTP screen (UI).
Responding to feedback on PR
The changes which you have done in your code as suggested in PR comments should be committed separately in a separate commit with the commit message as
fix(*): PR suggestions