Posted by Shailen Tuli, DPE
Today we're releasing the source code for the official Google I/O 2018 for Android app.
The 2018 version constitutes a comprehensive rewrite of the app. For many years, the app has used a ContentProvider + SyncAdapter architecture. This year, we rewrote the app using Architecture Components and brought the code in sync with the Android team's current recommendations for building modern apps.
We followed the recommendations laid out in the Guide to App Architecture for writing modular, testable and maintainable code when deciding on the architecture for the app. We kept logic away from Activities and Fragments and moved it to ViewModels. We observed data using LiveData and used the Data Binding Library to bind UI components in layouts to the app's data sources.
The overall architecture of the app can be summarized in this diagram:
We used a Repository layer for handling data operations. IOSched's data comes from a few different sources — user data is stored in Cloud Firestore (either remotely or in a local cache for offline use), user preferences and settings are stored in SharedPreferences, conference data is stored remotely and is fetched and stored in memory for the app to use — and the repository modules are responsible for handling all data operations and abstracting the data sources from the rest of the app. If we ever wanted to swap out the Firestore backend for a different data source in the future, our architecture allows us to do so in a clean way.
We implemented a lightweight domain layer, which sits between the data layer and the presentation layer, and handles discrete pieces of business logic off the UI thread. Examples.
We used Dagger2 for dependency injection and we heavily relied on dagger-android to abstract away boilerplate code.
We used Espresso for basic instrumentation tests and JUnit and Mockito for unit testing.
The use of Firebase technologies has grown in the app as the Firebase platform has matured. The 2018 version uses the following Firebase components:
- Cloud Firestore is our source for all user data (events starred or reserved by a user). Firestore gave us automatic sync and also seamlessly managed offline functionality for us.
- Firebase Cloud Functions allowed us to run backend code. The reservations feature heavily depended on Functions checking a user's status (only attendees were allowed to make reservations), checking space availability and persisting reservation status in Firestore.
- Firebase Cloud Messaging let us inform the app about changes to conference data on our server. Conference data is mostly static, but it does change from time to time, especially after the keynote. The app has traditionally used a ping-and-fetch model when working with conference data, and we retained that usage this year.
- Remote Config helped us manage in-app constants. In previous years, we had found ourselves unable to inform users when data not directly related to the conference schedule — WiFi information, conference shuttle schedule, etc. — changed unexpectedly. Remote Config helped us update such values in a lightweight manner.
We made an early decision to rewrite the app from scratch to bring it in line with modern Android architecture. Using Kotlin for the rewrite was an easy choice: we loved Kotlin's expressive, concise, and powerful syntax; we found that Kotlin's support for safety features including nullability and immutability made our code more resilient; and we leveraged the enhanced functionality provided by Android Ktx extensions.
At I/O 2018, the Material Design team announced Material Theming, giving apps much greater ability to customize Material Design to bring more of their product's brand. As we launched the app before Material Theming, we couldn't use all of the new components but we managed to sneak a couple in like the new Bottom App Bar with inset Floating Action Button and we were able to incorporate a lot of the conference's branding elements.
The rewrite of the app brings the code in sync with Android's opinionated recommendations about building apps, and it resulted in a cleaner, more maintainable codebase. We'll continue working on the app, incorporating JetPack components as they become available and finding opportunities to showcase platform features that are good fits for the app. Developers can follow changes to the code on GitHub.