KOTLIN TIP #6

OBJECT EXPRESSIONS

Object expressions allow for strict singleton definition so there’s no mistaking it for a class that can be instantiated. They also ensure that you do not have to store singletons somewhere like in the Application class or as a static class variable.

For example, if I have a utility class with static thread-related methods I want to access throughout the app:

import android.os.Handler
import android.os.Looper
// notice that this is object instead of class
object ThreadUtil {
fun onMainThread(runnable: Runnable) {
val handler = Handler(Looper.getMainLooper())
handler.post(runnable)
}
}

 

ThreadUtil is called later in the typical way you would call a static class method:

ThreadUtil.onMainThread(runnable)

This means there’s no more declaring a constructor as private, or having to figure out where the static instance is stored. Objects are essentially first class citizens of the language. In a similar way, we create objects instead of anonymous inner classes:


viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float,
positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
bindUser(position)
}
})

Both of these do essentially the same thing — create a single instance of a class as a declared object.

Organizing Your Android Development Code Structure

Writing a medium to large Android app requires having code structure. In creating our latest Android development project, I came across a lot of problems handling the structure and then I searched and found a simple way of structuring as below that helped me out.

Java Code

I like to have separate files for each class in my Android projects, the only exception being AsyncTasks. Having this many java files means you have to have more packages than the base package. I ended up with a package for each type of main class. Each class is named ending with its type.

com.example

activities

Contains all the activities. Classes are all named with Activity at the end. That way, you can immediately know what it is when reading Java code that doesn’t have its full package name.

adapters

Contains all the adapters.

authenticator

Contains any class related to signing a user in. I create a local account and having all related classes together is very handy.

data

Contains all classes related to data management such as ContentProvider and SQLiteHelper.

data.migrations

Contains all of my SQLite migrations. I created a class for migrations, read about it here, and put them all in this package.

fragments

Contains all fragments.

helpers

Contains helper classes. A helper class is a place to put code that is used in more than one place. I have a DateHelper for instance. Most of the methods are static.

interfaces

Contains all interfaces.

models

Contains all local models. When syncing from an HTTP API I parse the JSON into these Java objects using Jackson. I also pull Cursor rows into these models as well.

preferences

Contains all classes for custom preferences. When creating the preferences I required a custom PreferenceDialog as well as a custom PreferenceCategory. They live here.

sync

Contains all classes related to syncing. I use a SyncAdapter to pull data from an HTTP API. In addition to the SyncAdapter a SyncService is required, so I created a package.

Layouts

The layouts folder can easily become disorganised since you can’t have any folders in it. This is a known issue and has been ignored for 4 years now. To get around this I name my layout files with a prefix depending on what they are for. This sorts them together in the android studio file listing.

R.layout

activity_

adapter_

fragment_

IDs

All of my IDs are snake_case. I had a project that was inconsistent with how IDs were named and it was a pain. Many projects seem to do mixedCase notation for IDs, but it seemed weird having the different styles in Java code depending on what type of resource it was, e.g. R.layout.snake_case vs R.id.mixedCase.

Values

For values I have a separate file for each type of resource, e.g. dimens.xml. This works out well for most of the values, except for strings. There are a large amount of strings in this app and having them all in the same file is pretty unusable. In this case I split out some of the strings into groups by their activity. This allows you to easily find a string if you’re looking at the activity already.

How do you structure your code for Android app development projects? Is there any better way to follow? Comment and let me know.