Take home challenge from NAB in partnership with Positive Thinking Company

Android CI

Software development principles, patterns and practices


  • Program to an interface, not an implementation – Every methods of repository is called through Interface, not their implementation. Because of this, it is easier to add new repositories without changing the implementation
  • Seperation of concerns – Seperate the app architecture into layers, each layer has its own responsibility
  • Single Responsibility – One method does one thing
  • Inversion of Control – Use dependency injection library Hilt to avoid dependencies between components


  • Observer Pattern – In UI Controllers, observe changes from data in ViewModel to take actions
  • Factory Pattern – Use ViewModelFactory to get ViewModel instance based on the type and constructor params
  • Builder Pattern – Construct Retrofit, Moshi with builder to avoid calling constructor with so many params
  • Singleton Pattern – Make repositories components, API instance as singleton so that there is only one instance of these during the app lifecycle
  • MVVM Pattern – Model, View, View-Model for testable code and robust architecture


  • Regex – Used to validate data based on specific format
  • Unit test – Make sure that functions run in right way
  • Two Way data binding – When the data on the View changes, the binded property in ViewModel will update automatically
  • CI/CD with Github Action – Make a build when code in this repository changes. If this fails, notify through email about the result
  • DiffUtils – Improve performance of RecyclerView in Android
  • Secure app – Use Proguard to minify, obfuscate code, remove unused resource for both release and debug build

Libraries & frameworks

  • Github Action – Create build assembles whenever code is updated
  • Timber – Logging
  • Retrofit2 – Construct the REST APIs and paging network data
  • Moshi – A modern JSON library for Kotlin and Java
  • Hilt – A dependency injection library
  • AppCompat – Degrade gracefully on older versions of Android
  • Test/Junit – An Android testing framework for unit tests
  • Data Binding – Declaratively bind observable data to UI elements
  • Lifecycles – Create a UI that automatically responds to lifecycle events
  • LiveData – Build data objects that notify views when the underlying datasource changes
  • Navigation – Handle everything needed for in-app navigation
  • Kotlin Coroutine – Handle long running operation outside main thread

Folder structure

  • data: Contains mostly code related to acess data
    • network: Setup code for API service along with its methods to get the data
    • repository: Implementation code for the repository in the domain
  • di: Dependency Injection modules that are used across the app
  • domain: Contains the logic, model accross the app, related to business
    • dto: Data Transfer Objects, used to receive data from remote with Json properties
    • model: Domain Model Objects, contain data and some logics related to the object in app
    • repository: Interface only, define a contract that is needed to access data
    • utils: Helper methods to handle data
  • presentation: Contains the logic, code to display data
    • dailyforecast: A screen folder, contains its related file such as ViewModel, UI Controller (Fragments, Activities), ViewModelFactory
    • utils: Some base or helper methods


Run by installing APK

  1. Go to the list of builds created here
  2. Choose the latest one with green tick (Sucessfully built)
  3. Download the
  4. Extract downloaded file and install the APK file

Run in Android Studio


  • Android Studio version 4.2.2 and above
  • SDK version from 23 to 30
  • Emulator from API 23
  1. Clone this project
  2. Open in Android Studio
  3. Click Run

Note for the Average Temperature calculation:
Because the Average Temperature is calculated by sum of each measurements, then divided by the times, according to the API, the Average Temperature calculation formula is as below:

Averrage Temperature = SumOf(morning, day, evening, night) / 4


  • 1. Programming language: Kotlin is required, Java is optional.
  • 2. Design app’s architecture (suggest MVVM or you can use any architectures that you get
  • 3. Apply LiveData mechanism or any mechanism that you get familiar with
  • 4. UI should be looks like in attachment.
  • 5. Write UnitTests (nice to have)
  • 6. Secure Android app from:
    • a. Decompile APK
    • b. Rooted device (optional)
  • 7. Exception handling (optional)
  • 8. Readme file includes:
    • a. Brief explanation for the software development principles, patterns & practices being
    • b. Brief explanation for the code folder structure and the key Java/Kotlin libraries and
      frameworks being used
    • c. All the required steps in order to get the application run on local computer
    • d. Checklist of items the candidate has done




View Github