Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Android developer: Principles

Description

Please, first, checkout Developer: Principles. You must first "make own" these developer rules.

The following advices are very opinionated. Before saying "bullshit", please read the why below in the Details section. One of the main ability of developer is to understand the why. (this advice apply to myself of course. Every tool I'm criticising exist because of a why that I consider less important than the alternative).

The goal of this document is more to start a reflection than make you change your code.

Keep in mind that these rules are in a context of a long term support of applications / libraries. These are related to my needs.

5suohe

Here are best practices as an Android developer.

Principles

# Principles
1 Do not use Fragment -> use Activity and Views
2 Do not use GSON -> use JsonObject
3 Do not use reactive programmation -> use classic programmation
4 Do not use Retrofit and OkHttp with asynchronous API -> use synchronous OkHttp or Ktor
5 Do not use coroutine and suspend -> use synchronous methods on a worker thread
6 Do not use lib for Dep. Inj -> use hand made Dep.Inj
7 Do not use MVVM and Google View Model -> use MVP
8 Do not use Jetpack Compose -> use xml
9 Do not use one gradle modle -> use multiple gradle modules with samples
10 Do no use Toolbar and BottomNavigationView -> use your own custom view
11 Do not use Navigation component -> use your own navigation
12 Split resources by feature matching your packages
13 Prefix resource ids and layout by feature name, prefix layout ids by layout name
14 Do the view binding yourself
15 Do not make variable name, class name or package name impact the apk (when possible)

Details

1. Do not use fragment

Why?

2. Do not use GSON

3. Do not use reactive programmation

Reactive programmation is a pradigm that impact the whole project. If done correclty, you cannot isolate the "rectivity" to a small part of the code (why? consistency).

So, with that in mind, why do I think "reactive programmation" is not the way to go

  • Because one of the main principle, is to keep the code easy to read, understandable most people (juniors...). On board new developer is key! Reactive programmation is not one isolated feature, that change the whole codebase.
  • Because a lot of libraries and third parties will not use reactive programmation

Keep in mind the first rule of developer: keep it simple, easy to read in order to easily onboard new developpers.

7. Do not use MVVM and Google View Model

Why does design pattern for the "view" exist?

  • a. To split the "view" from the "logic" code
  • b. To split the "platform specific" code from the "logic" code

Why the a.

  • To unit test the "logic" part of the code
  • To have the "logic" part of the code working with "any" UI
  • Because UI is more subject to change, and we do not want to break the logic with small UI changes (Uncle Bob argument)
  • To avoid 3000 line long Activity (was the state once, on one of the project I was working on)

Why the b.

  • To be able to run the logic code on your computer (or on a CI)
  • To be able to produce "similar code" whatever the platform (I mean, code with similar concepts)

So, with that, why do I think the Google way of MVVM is not the way to go

  • Because "ViewModel", everywhere else, is a model crafted specificly to meet the View needs
  • Because one of the main principle, is to keep the code easy to read, understandable most people (juniors, non pure Android dev...). Keep in mind that Android is using jvm code (kotlin and java), so a lot of the code an app is platform agnostic.

8. Do not use Jetpack Compose

Because Jetpack Compose cannot be isolated to the view. UI should not drive your architecture. Avoid strong dependency is key to have robust code.

// WIP

13. Prefix resource ids and layout by feature name, prefix layout ids by layout name

On Android, all the resources are accessible by the whole code (resources are not feature private on the same gradle module). To avoid conflict, prefix your resources. This rules is even more important for resources in shared gradle modules / on libraries.

I remember when I was coding on Unity, libraries that have "app_name" resources ^^. That may force your client to use "replace" in xml, this situation could be avoidwith prefix.

14. Do the view binding yourself

With the rule 13. every id is unique so could be long. View binding done by Android can allow you to have field directly accessible with res id as field name. Avoid that. Resource ids are lowercase with _, fields should use cameCase.

Here how to do that:

// On Activity
private val version: TextView by bind(R.id.settings_activity_version)
private fun <T : View> Activity.bind(@IdRes res: Int): Lazy<T> {
    return lazy(LazyThreadSafetyMode.NONE) { findViewById(res) }
}

// On CustomView
private val view = inflate(context, R.layout.section_bar_view, this)
private val galleryIconOn: ImageView = bind(R.id.section_bar_view_gallery_icon_on)
@Suppress("SameParameterValue")
private fun <T : View> bind(@IdRes id: Int): T {
    @Suppress("RemoveExplicitTypeArguments")
    return view.findViewById<T>(id)
}

15. Do not make variable name, class name or package name having an impact on the binary when possible

  • When you use GSON without annotation for example, the field name of the class are use as JSON keys
  • When you have an enum and use ColorEnum.WHITE.name
  • When you use java reflect

All the use should be avoid (exception for the java reflect, something, no other choice)

Why?

Because be able to refacto without any fear is what's make the codebase robust. You should be able to change variable and classe names without breaking the product. As a developer, it is fair to assume we can rename a classes whithout breaking the product.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment