Simple Guide to Android App Architecture

Umesh Ramani
4 min readJul 22, 2019

--

For a large android application, there is always a question,

“What should be the architecture of an app which is robust, testable and provides high scalability?”

This tutorial will guide you for best practise and app architecture recommended by Google for building robust and highly-productive android application in a very simple way.

As per this architecture, our app should follow the principle of Separation of concerns. In this approach, each component will perform his own task and will not interfere in anyone’s core responsibility. They should be independent of each other.

This divides our app into three main parts

1) Activity/Fragment — it deals with inflating layout, initialising variables and functions, set visibility of view and any task related to UI. Activity/Fragment will request ViewModel to get the data required to display on screen

2) ViewModel — This class should contain the business logic for a activity/fragment. ViewModel class will not deal with any view and it should not have any reference to views or context of activity.

Its sole responsibility is to execute business logic and send the output back to Activity/Fragment.

3) Data Source Repository — This class is responsible for fetching the data for the viewModel.

ViewModel will request Repository to provide data. Data can be fetch from either server or from database or any other source. For a data request from ViewModel, repository will gather the required data and sends back to the ViewModel.

Here is the pictorial view for the architecture.

Sounds good???.
This is the theoretical part. Now lets jump into implementation part.

To implement it, we will use following things in our project

Room — An architecture component and Sqlite database helper, provides ways to persist data in sqlite database. We will use Room to store, fetch and display data into list
ViewModel — To perform business logic
Coroutines — Used for background processing instead of thread
LiveData — Observable data
Data Binding — Model to view binding in adapter
RecyclerView — Used to show list of records retrieved from sqlite database

Note: If you are not familiar with above concepts, please go through it before proceed.

For a visualisation let see how it looks

To proceed, lets we divide our task into steps as

1. Setup Room
2. Add dependency for viewModel, data binding and coroutines
3. Create ViewModel class
4. Create Repository class
5. Create activity class and add observer to Livedata returned from viewModel
6. Request data From activity to viewModel
7. Request data from viewModel to Repository
8. Send data back from repository to viewModel
9. Send data back from viewModel to activity
10. Display data into recyclerview

Setup Room
To setup room, open your app’s build.gradle file and add following lines

apply plugin: ‘kotlin-kapt’
implementation “android.arch.persistence.room:runtime:1.1.1”
kapt “android.arch.persistence.room:compiler:1.1.1”

Sync your project.

Create a new kotlin class named RoomUtil.kt and add following line of code

@Database(entities = [SampleModel::class], version = 1, 
exportSchema = false)
abstract class RoomUtil : RoomDatabase() {
companion object {
private const val DB_NAME = “SampleDB”
private lateinit var instance: RoomUtil
fun init(context: Context) { abstract fun sampleDao(): SampleDAO instance = Room.databaseBuilder(context, RoomUtil::class.java,
DB_NAME)
.allowMainThreadQueries()
.addMigrations()
.build()
// To add dummy data
addData()
}
fun getInstance(): RoomUtil {
return instance
}
fun addData() {
getInstance().sampleDao().insertData(SampleModel(1,
“John”,
“Smith”))
}
}
}

Add dependency for viewModel, data binding and coroutines.
We will now add required dependencies. Add following dependencies into app level build.gradle file.

// View model
def lifecycle_version = “1.1.1”
implementation“android.arch.lifecycle:extensions:$lifecycle_version”
//Coroutines
implementation “org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1”
implementation “org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1”
Also add this into the android block
dataBinding {
enabled = true
}

Create ViewModel class
Create ViewModel class for activity.

class SampleViewModel : ViewModel() {private val repo = SampleRepository()val mediatorLiveData = MediatorLiveData<List<SampleModel>>()fun getList() {//We will use coroutine instead of Thread to get data in background.
//Code in launch block will be executed in main thread.
//However, we have used suspend function in Repository class to get //data in background thread.
(CoroutineScope(Dispatchers.Main) + Job()).launch {
mediatorLiveData.addSource(repo.getList()) {
mediatorLiveData.value = (it)
}
}
}
}

Create Repository class
Create data Repository. Fetch the data in background thread.

class SampleRepository {
suspend fun getList(): LiveData<List<SampleModel>> {
return withContext(Dispatchers.IO) {
delay(3000)
RoomUtil.getInstance().sampleDao().getList()
}
}
}

Create activity class and add observer
Now open our activity class and add observer to our data we received from viewModel.

override fun onCreate(savedInstanceState: Bundle?) {
..............
RoomUtil.init(this)
adapter = SampleAdapter(this)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
viewModel = ViewModelProviders.of(this).get(SampleViewModel::class.java)//Add observer to our livedata
viewModel.mediatorLiveData.observe(this, Observer {
adapter.setList(it)
})
viewModel.getList()...............
}

We have created files and added necessary code into it to achieve our purpose.

For this tutorial, we have skipped setting up data to recyclerView and other common android things. However, you can download and refer the full working project from here.

And thats it. Its done!!

To summarise, let see how the app works in a pictorial view,

Here, numbers in green circle are steps, as following

  1. Activity Needs data for displaying on screen. It requests to viewModel for the data.
  2. ViewModel request to Repository for the data.
  3. Repository will look for data source. It may be either from database or remote server.
  4. Data will be fetched from database/remove server.
  5. Requested data is ready to repository from step 4.
  6. Repository send data back to ViewModel.
  7. ViewModel sends data back to activity.
  8. Activity displays data on screen.

Congratulations. You are a master of android app architecture!!

Happy coding.

Project Download Link

--

--