Skip to content
master
Go to file
Code

Latest commit

* Report fully drawn in the main/home activity

The Feed is the main view that launches when the app opens (after onboarding). Once the feed items are fetched, we post reporting fully drawn until after the recycler view finishes drawing the items.

Activity#reportFullyDrawn() prints a log statement that looks like this:
I/ActivityTaskManager: Fully drawn com.google.samples.apps.iosched/.ui.MainActivity: +3s493ms

Reporting fulling drawn from onboarding and deeplinking into SessionDetails will be in follow up CLs.

Bug: 158839978
Test: Manually check for the log statement from the framework
Change-Id: I5d4f6f2f93aaa7f0edcc12442d6b30d87dc76107

* Report fully drawn from SessionDetailActivity

When a user opens a deeplink into the session details, we should report when the screen has been fully drawn.

Activity#reportFullyDrawn() prints a log statement that looks like this:
I/ActivityTaskManager: Fully drawn com.google.samples.apps.iosched/.ui.sessiondetail.SessionDetailActivity: +516ms

Change-Id: Ib2b8ad08a6a7b8a7459e9412f2ebb180991a3f0c

* Report fully drawn from OnboardingActivity

Depending on the time, we have several entrance onboarding screens presented to the user. The content in hardcoded so we can report fully drawn as soon as the views are rendered.

Activity#reportFullyDrawn() prints a log statement that looks like this:
I/ActivityTaskManager: Fully drawn com.google.samples.apps.iosched/.ui.onboarding.OnboardingActivity: +3s87ms

Change-Id: I1295ae041560da539475630726bb0ce71aa470b4

* Use EventObserver instead when observing fullyDrawn

Change-Id: I2d53bba09839548df4eabcdcae060d8398b98327

* Clean up comment around reportFullyDrawn()

Change-Id: I2955ae253ac49c2d8478263ea05ebc8e3c98f648

* Address minor comments from jdkoren

Change-Id: Ifb619989923890c6d453f416659c81fabe10105d

* Call reportFullyDrawn directly on the activity form the fragment

Change-Id: I36b4252fa779a2479d8d9106d3a6ea28888e0ef9

* Removed unused imports

Change-Id: Id7402173643b953526d2c69923330df49100cae2
b428d2b

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time

README.md

Google I/O Android App

Build Status

Due to global events, Google I/O 2020 was canceled and thus an Android app update was not released to Google Play. However, prior to the cancellation, the team implemented several architecture improvements, reflected in the code published in June, 2020. The general look and feel of the app is unchanged, and the app still uses the data from Google I/O 2019.

Google I/O is a developer conference with several days of deep technical content featuring technical sessions and hundreds of demonstrations from developers showcasing their technologies.

This project is the Android app for the conference.

For a simpler fork of the app, check out the Android Dev Summit App in the adssched branch. In this variant some features are removed, such as reservations and the map screen, and Instant App support is added.

Features

The app displays a list of conference events - sessions, office hours, app reviews, codelabs, etc. - and allows the user to filter these events by event types and by topics (Android, Firebase, etc.). Users can see details about events, and they can star events that interest them. Conference attendees can reserve events to guarantee a seat.

Other features include a Map of the venue, informational pages to guide attendees during the conference in Info, and time-relevant information during the conference in Home.

Schedule screenshot

Development Environment

The app is written entirely in Kotlin and uses the Gradle build system.

To build the app, use the gradlew build command or use "Import Project" in Android Studio. A canary or stable version of Android Studio 4.0 or newer is required and may be downloaded here.

Architecture

The architecture is built around Android Architecture Components.

We followed the recommendations laid out in the Guide to App Architecture 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.

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, etc. - and the repository modules are responsible for handling all data operations and abstracting the data sources from the rest of the app (we liked using Firestore, but if we wanted to swap it out 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. See the .\*UseCase.kt files under shared/domain for examples.

We used Navigation component to simplify into a single Activity app.

We used Room for Full Text Search using Fts4 to search for a session, speaker, or codelab.

We used Espresso for basic instrumentation tests and JUnit and Mockito for unit testing.

For 2020, we added several Jetpack libraries:

  • We added the Jetpack Benchmark library. The Benchmark library makes it easy to benchmark your code from within Android Studio. The library handles warmup, measures your code performance, and outputs benchmarking results to the Android Studio console. We added a few benchmark tests around critical paths during app startup - in particular, the parsing of the bootstrap data. This enables us to automate measuring and monitoring initial startup time. Here is an example from a benchmark run:
Started running tests

Connected to process 30763 on device 'google-pixel_3'.
benchmark:
benchmark:    76,076,101 ns BootstrapConferenceDataSourceBenchmark.benchmark_json_parsing
Tests ran to completion.
  • We migrated from dagger-android to Hilt for dependency injection. This allowed us to remove 75% of the dependency injection code, and also resulted in a 13% build time improvement.

  • We migrated to ViewPager2 for our view paging needs. ViewPager2 offers enhanced functionality over the original ViewPager library, such as right-to-left and vertical orientation support. For more details on migrating from ViewPager to ViewPager2, please see this migration guide.

Firebase

The app makes considerable use of 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 Cloud Functions working in conjuction with Firestore.
  • Firebase Cloud Messaging let us inform the app about changes to conference data on our server.
  • Remote Config helped us manage in-app constants.

For 2020, we migrated to the Firebase Kotlin extension (KTX) libraries to write more idiomatic Kotlin code when calling Firebase APIs. To learn more, read this Firebase blog article on the Firebase KTX libraries.

Kotlin

We made an early decision to rewrite the app from scratch to bring it in line with our thinking about modern Android architecture. Using Kotlin for the rewrite was an easy choice: we liked Kotlin's expressive, concise, and powerful syntax; we found that Kotlin's support for safety features for nullability and immutability made our code more resilient; and we leveraged the enhanced functionality provided by Android Ktx extensions.

For 2020, we migrated to coroutines for asynchronous tasks. Coroutines is the recommended way to do asynchronous programming in Kotlin. We also migrated our build scripts to Kotlin DSL.

Copyright

Copyright 2014 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
You can’t perform that action at this time.