Open-source project
JakeWharton/u2020 avatar
JakeWharton/u2020

u2020: Jake Wharton's Reference Android App for Dagger, Debug Drawer, and Mock Mode

GitHub describes it as A sample Android app which showcases advanced usage of Dagger among other open source libraries.. The repository metadata lists Java as its primary language. The metadata lists the Apache-2.0 license. This article stays within the project description and details documented in the GitHub repository README.

5,614 stars907 forksJavaApache-2.0

At a glance

What is it?
u2020 is a sample Android application by Jake Wharton that demonstrates advanced Dagger dependency injection alongside libraries including Retrofit, OkHttp, Picasso, RxJava, and LeakCanary. It introduces the Debug Drawer pattern for developer tooling and a Mock Mode that replaces network calls with in-memory data for testing. The last push was on 2023-05-28.
Who is it for?
u2020 is worth reading if you are building a production Android application that uses Dagger for dependency injection and want a concrete reference for structuring debug and release module graphs, implementing a Debug Drawer for developer options, or using Mock Mode to run integration tests without a live server. It is not a library to import and is not intended as a starting template; it is a documented example of specific architectural decisions.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Probably not. The repository last received commits 40 months ago, on May 28, 2023.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What u2020 Demonstrates

u2020 exists to show how Dagger dependency injection can be used at the scale of a full Android application with multiple build types, multiple service layers, and developer tooling that should be absent from release builds. The app displays trending GitHub repositories and is simple enough that the architecture is visible without being obscured by business logic. Jake Wharton presented the project at Devoxx 2013, and the README links to both the talk video and the slide deck. The architectural decisions it demonstrates have influenced how Android teams structure dependency injection: the release and debug build type split, the override module pattern for substituting real implementations with fakes, and the Debug Drawer for exposing developer options at runtime. These patterns were novel in 2013 and were widely adopted across the Android ecosystem.

Dagger Module Graph and Build Type Split

The ObjectGraph is created in U2020App's onCreate method. A class named Modules provides a single list() method that returns the module instances to include in the graph. This class exists in both the release/ and debug/ source sets. The release version includes only U2020Module. The debug version includes both U2020Module and DebugU2020Module, the latter of which is present only in the debug source set and is an override module. This structure ensures that debug-only code never appears in a release build: the Dagger module graph is assembled differently depending on which source set is active at build time, without any if-statements in shared code. This technique avoids the common mistake of wrapping debug features in if (BuildConfig.DEBUG) checks throughout the codebase.

Getting the Code and Its Dependencies

Clone the repository and build with Gradle:

java
@Singleton class MockFoo() {
  @Inject MockFoo() {}
  // ...
}

The above snippet from the README illustrates a mock class that Dagger can inject in place of the real implementation. The override module wires it in:

java
@Provides @Singleton Foo provideFoo(@IsMockMode boolean isMockMode, MockFoo mockFoo) {
  return isMockMode ? return mockFoo : new RealFoo();
}

This @IsMockMode qualifier is a boolean binding set in DebugDataModule. When Mock Mode is active, Dagger injects MockFoo wherever Foo is requested. The build.gradle and gradlew files at the root of the repository are the entry points for building and installing the app. The top-level entries include app/, service/, and intent-factory/ source directories as well as the standard gradle/ wrapper files.

The Debug Drawer Pattern

The Debug Drawer is a panel that slides in from the right edge of the screen in the debug build, triggered by a bezel swipe. It is injected via the ViewContainer interface. The default implementation returns the standard Android content view. The debug version overrides this with DebugViewContainer, which creates the drawer, adds it to the activity layout, and returns its content view group. DebugViewContainer injects developer objects and binds them to controls in the drawer. Through the drawer, a developer can change the API endpoint at runtime using a spinner, switch into Mock Mode, adjust fake network behavior (latency, error rate), and toggle other developer options. This approach makes the debug tooling a first-class part of the dependency graph rather than scattered conditional code, and it is accessible to anyone running a debug build without requiring Android Studio or ADB.

Mock Mode and the ServerDatabase

Mock Mode replaces the real HTTP API layer with in-memory implementations that serve static data. This has two practical benefits. Manual testing does not require network connectivity or a running backend. Instrumentation tests run against a stable, predictable dataset. The shared state across mock services is maintained by a ServerDatabase singleton, which holds in-memory collections and images stored in debug/assets/. Each mock service (such as MockGalleryService) injects ServerDatabase and reads from or writes to it. The README notes that a more complex application could use a full SQLite database for the mock backend; the in-memory approach is appropriate for an app with a single data entity (trending repositories). The @IsMockMode qualifier allows modules to branch on whether Mock Mode is active, as shown in the provideFoo example in the README. Mock Mode can be toggled from the Debug Drawer at runtime without recompiling, which makes it easy to switch between live API calls and fake data during a debugging session on a development device.

The Library Ecosystem and Maintenance Status

u2020 integrates a set of libraries that were the standard Android stack at the time: Dagger 1.x by Square for dependency injection, Retrofit for HTTP, OkHttp for the underlying connection layer, Picasso for image loading, Moshi for JSON, RxJava for reactive streams, ButterKnife for view binding, Timber for logging, LeakCanary for memory leak detection, Scalpel for 3D view layer inspection, Madge for pixel grid debugging, ProcessPhoenix for restarting the process cleanly, and Telescope for screenshot capture and bug reporting. Several of these libraries have had major version changes since 2013: Dagger 2 replaced Dagger 1 with a completely different API, ButterKnife is no longer actively developed, and view binding now has first-party support in Android. The codebase reflects 2013-era patterns. The last push to this repository was on 2023-05-28, and it has no GitHub releases, so the library versions have not been updated to reflect the current Android ecosystem.

Editorial conclusion

u2020 is worth reading if you are building a production Android application that uses Dagger for dependency injection and want a concrete reference for structuring debug and release module graphs, implementing a Debug Drawer for developer options, or using Mock Mode to run integration tests without a live server. It is not a library to import and is not intended as a starting template; it is a documented example of specific architectural decisions. The last push was on 2023-05-28, so the library versions and Dagger 1.x API in the codebase are dated relative to current Android development. The patterns themselves (override modules, Mock Mode, Debug Drawer) remain applicable with Dagger 2 and Hilt, though the API surface differs.

Frequently asked questions

What is u2020 and who is it for?

u2020 is a sample Android application by Jake Wharton that demonstrates advanced Dagger dependency injection, the Debug Drawer pattern, and Mock Mode for in-memory testing. It is for Android developers who want a concrete reference implementation for structuring debug and release dependency graphs.

Does u2020 use Dagger 2 or Hilt?

u2020 uses Dagger 1 (the original Square/JakeWharton Dagger based on ObjectGraph). The last push was on 2023-05-28 and the codebase has not been migrated to Dagger 2 or Hilt. The architectural patterns transfer to Dagger 2, but the API calls differ.

What is the Debug Drawer in u2020?

The Debug Drawer is a slide-in panel accessible in debug builds by swiping from the right bezel. It exposes developer options including endpoint switching, Mock Mode activation, and fake network behavior controls. It is injected via the ViewContainer interface and is absent from release builds entirely.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jakewharton-u2020.svg)](https://hysenlabs.com/projects/jakewharton-u2020)