u2020: A Dagger 1 Era Android Sample That Still Teaches Build Type Overrides
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.
At a glance
- What is it?
- Jake Wharton's u2020 is an Android sample app built around Dagger 1 that demonstrates how to use build type specific modules and override graphs to add a debug drawer, mock endpoints, and in-memory servers. It is a historical artifact, but its core patterns remain instructive.
- Who is it for?
- Adopt u2020 if you are learning how Dagger 1 structured object graphs and how build type specific modules can separate debug from release behavior. It is not a template for modern Android development: it uses Dagger 1, Java, and libraries like ButterKnife that have been superseded.
- 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 42 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 November 14, 2026, and from our analysis. They are not legal advice.
Star history
- JakeWharton/u20205,613 ★ · -9
| Repository | 2026-08-13 | 2026-11-14 |
|---|---|---|
| JakeWharton/u2020 | 5.6k | 5.6k |
-9 Stars in the last 93 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What u2020 Actually Demonstrates
u2020 is a sample Android application that exists to show advanced usage of Dagger, the dependency injection framework that Square maintained before Dagger 2. The README is explicit: it showcases advanced usage of Dagger among other open source libraries. The target audience is Android developers who already know the basics of Dagger and want to see how a real app organizes modules, handles build type differences, and wires a debug-only UI. The app itself is a gallery of trending images, but the content is secondary. The point is the plumbing. The repository dates from 2014, and the code is written in Java. It is not a library you add to your project. It is a reference implementation you read and possibly copy patterns from.
The Mechanism: Build Type Modules and Override Graphs
The core architectural trick in u2020 is the separation of modules by build type. The README explains that the ObjectGraph is created in the U2020App's onCreate method. The Modules class provides a single method, list, which returns the list of module instances to use. This class lives in both the release and debug build type folders, but with different contents. The release version only includes U2020Module. The debug version includes both U2020Module and DebugU2020Module. DebugU2020Module is an override module, meaning it can replace bindings from the base module. This is a Dagger 1 feature: override modules allow you to substitute implementations at graph construction time. In this case, the debug build replaces the default ViewContainer with DebugViewContainer, which is responsible for creating the debug drawer, adding it to the activity, and injecting developer objects into it. The override mechanism is what makes the debug drawer possible without touching the release code path.
The Debug Drawer and ViewContainer Indirection
The debug drawer is the most visible feature of u2020. It is opened by a bezel swipe from the right of the screen, and it exposes developer options such as endpoint switching. The drawer is provided by a simple interface called ViewContainer. This interface is an indirection that the single activity uses to fetch its content container. The default implementation returns the Android-provided content view. In the debug build, DebugViewContainer overrides that: it creates the drawer, adds it to the activity, and returns its content view group. It also injects all the developer objects and binds them to controls in the drawer. This design is clean because the activity does not know about the drawer at all. It only knows about ViewContainer. The debug build swaps in a different implementation, and the activity is none the wiser. That is a pattern worth studying, even if you never use Dagger 1 again.
Mock Mode and In-Memory Server Simulation
The most notable debug feature is the ability to change endpoints via a spinner at the top of the drawer. One of those endpoints is a false endpoint named Mock Mode, which simulates an in-memory server inside the app. The README explains that Mock Mode eases manual testing and provides a static set of data to write instrumentation tests against. The mechanism works because modules can query whether Mock Mode is active when they configure their dependencies. The README gives a code example: a provider method takes a boolean parameter annotated with @IsMockMode, and if that boolean is true, it returns a MockFoo instance; otherwise it returns a real implementation. This is a simple but effective way to switch between real and fake dependencies at runtime. The mock services share state through a ServerDatabase singleton, which is injected into each mock service. For now, that state is a combination of in-memory collections and images in the debug/assets folder. In a more complex app, you could use a full database. The point is that the dependency injection graph makes this kind of runtime switching trivial.
Getting It Running: Commands and Configuration
The README does not include build commands, but the repository is a standard Android project from the Gradle era. You would clone it and open it in Android Studio, or run gradle assembleDebug from the command line. The key configuration is the build type folders: the Modules class exists in both release and debug source sets, and DebugU2020Module is only present in the debug folder. This is a Gradle source set convention: files in src/debug/java are included only in debug builds. The README does not mention a specific Gradle version, but given the 2014 date, it likely uses an old Android Gradle plugin. You will probably need to update the build files to run it with a modern toolchain. The README also lists the libraries used, including Dagger, ButterKnife, Retrofit, Moshi, Picasso, OkHttp, RxJava, Timber, Madge, ProcessPhoenix, Scalpel, LeakCanary, and Telescope.
Real Limitations and Known Failure Modes
The README itself lists three to-do items that are honest about the app's limitations. First, there is something to do with animations to showcase animation control, meaning that feature is not implemented. Second, network errors probably crash the app. That is a direct quote from the README, and it is a serious caveat for anyone who wants to use this as a stable sample. Third, the app only has one part, trending, so there is no demonstration of child graphs. The README says they want to add another part to demo child graphs. These are not hypothetical concerns; they are stated as unfinished work. For a sample app, that is acceptable, but it means you should not rely on u2020 as a reference for error handling or for multi-screen graph scoping. The app is also tied to Dagger 1, which is deprecated. If you are learning modern DI, u2020 will teach you patterns that do not translate directly.
Alternatives and Evolution of the Pattern
The direct alternative to u2020 is Dagger 2's own sample projects or the Google Android Architecture Blueprints. Dagger 2 replaced the runtime object graph with compile-time code generation, and it uses subcomponents instead of override modules. The override mechanism in Dagger 1 is replaced by @Component dependencies or subcomponents in Dagger 2. The debug drawer pattern is still possible, but you would define a debug component that extends or depends on the main component. The build type source set trick still works with Gradle, so you can keep the debug-only module in src/debug/java. Another alternative is Hilt, which is built on top of Dagger 2 and provides a standard way to integrate with Android lifecycle components. Hilt does not have the same override mechanism, but you can use build type variants to provide different bindings. The core idea of u2020, separating debug and release behavior through DI, survives in all of these. What changes is the syntax and the tooling.
Maintenance and License Considerations
The repository is not archived, but the last push was on 2023-05-28 and there are no GitHub releases. The README's copyright is 2014. This means the project is effectively unmaintained. You will likely encounter build failures with current Android Gradle Plugin versions, and you will need to update dependencies or migrate to newer libraries. The license is Apache-2.0, which permits you to use the code in your own projects, including commercial ones, as long as you retain the license notice. That is a permissive license, so you can copy the debug drawer pattern or the Modules class structure into your own codebase. However, you should be aware that the code may contain bugs or outdated practices, and you are responsible for adapting it. The README's to-do list is a reminder that this is a work in progress, not a polished library. If you adopt patterns from u2020, verify that they still work with your current DI framework and Android API level.
Editorial conclusion
Adopt u2020 if you are learning how Dagger 1 structured object graphs and how build type specific modules can separate debug from release behavior. It is not a template for modern Android development: it uses Dagger 1, Java, and libraries like ButterKnife that have been superseded. Do not use it as a starting point for a new app. If you want to study the debug drawer and endpoint switching patterns, first verify that your current DI framework supports similar override mechanisms, or be prepared to adapt the ideas to Dagger 2 or Hilt. The repository is archived in practice, so expect no updates and no support for current Android tooling. The most concrete takeaway is the Modules class and the DebugU2020Module override: read those files before anything else.
Frequently asked questions
How does u2020 keep debug-only code out of the release build?
The Modules class exposes a single list method whose contents depend on build type. Release includes only U2020Module, while debug also includes DebugU2020Module, which exists only in the debug build type folder and is an override module.
What is Mock Mode in u2020?
It is a false endpoint named Mock Mode, selected from the same spinner in the debug drawer that changes real endpoints. It simulates an in-memory server inside the app, backed by a ServerDatabase singleton, so instrumentation tests have static data to run against.
How is the debug drawer opened in the u2020 sample app?
By a bezel swipe from the right edge of the screen. The drawer is provided through the ViewContainer interface, whose debug implementation is DebugViewContainer, and that implementation creates the drawer, attaches it to the activity and returns its content view group.
Which libraries does the u2020 sample app use?
Dagger, ButterKnife, Retrofit, Moshi, Picasso, OkHttp, RxJava, Timber, Madge, ProcessPhoenix, Scalpel, LeakCanary and Telescope.
Is the u2020 sample app still being updated?
The repository is not archived, but the last push was on 2023-05-28 and the project has no GitHub releases, so there is no published version history. The README also lists unfinished work, including that network errors probably crash the app.
Official sources
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.
[](https://hysenlabs.com/projects/jakewharton-u2020)Star history chart for your README
[](https://hysenlabs.com/projects/jakewharton-u2020)Was this useful?