{"id":13422613,"url":"https://github.com/JakeWharton/u2020","last_synced_at":"2025-03-15T12:30:45.848Z","repository":{"id":39618129,"uuid":"14393731","full_name":"JakeWharton/u2020","owner":"JakeWharton","description":"A sample Android app which showcases advanced usage of Dagger among other open source libraries.","archived":false,"fork":false,"pushed_at":"2023-05-28T12:22:30.000Z","size":9385,"stargazers_count":5672,"open_issues_count":14,"forks_count":927,"subscribers_count":326,"default_branch":"master","last_synced_at":"2025-03-14T13:02:48.229Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.youtube.com/watch?v=0XHx9jtxIxU","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JakeWharton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2013-11-14T11:58:23.000Z","updated_at":"2025-03-14T03:47:35.000Z","dependencies_parsed_at":"2024-01-07T01:20:16.451Z","dependency_job_id":null,"html_url":"https://github.com/JakeWharton/u2020","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JakeWharton%2Fu2020","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JakeWharton%2Fu2020/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JakeWharton%2Fu2020/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JakeWharton%2Fu2020/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JakeWharton","download_url":"https://codeload.github.com/JakeWharton/u2020/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243730982,"owners_count":20338748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T23:00:48.845Z","updated_at":"2025-03-15T12:30:45.827Z","avatar_url":"https://github.com/JakeWharton.png","language":"Java","funding_links":[],"categories":["Demos","CN","Index","Java","Libs","App","Showcases","App / Demo","Security"],"sub_categories":["dagger1","[Jake Wharton](https://github.com/JakeWharton)","Showcases","\u003cA NAME=\"Demo\"\u003e\u003c/A\u003eDemo","一些原理分析的文章"],"readme":"U+2020\n======\n\nA sample Android app which showcases advanced usage of Dagger among other open source libraries.\n\n[Watch the corresponding talk][video] or [view the slides][slides].\n\nThe `ObjectGraph` is created in the `U2020App`'s `onCreate` method. The `Modules` class provides a\nsingle method, `list`, which returns the list of module instances to use.\n\nIn order to add functionality in the 'debug' version of the app, this class is only present in the\n`release/` and `debug/` build type folders. The 'release' version only includes the `U2020Module` while\nthe 'debug' version includes both `U2020Module` and `DebugU2020Module`, the latter of which is only\npresent in the `debug/` build type folder and is an override module.\n\nThrough the use of Dagger overrides, the 'debug' version of the app adds a slew of debugging\nfeatures to the app which are presented in the Debug Drawer™. The drawer is opened by a bezel\nswipe from the right of the screen. From here you can change and view all of the developer options\nof the application.\n\nThe drawer is provided by the simple interface `ViewContainer`. This is an indirection that the\nsingle activity uses to fetch its container into which it can place its content. The default\nimplementation returns the Android-provided content view. The 'debug' version overrides this with\n`DebugViewContainer` which is responsible for creating the drawer, adding it to the activity, and\nreturning its content view group. It also injects all of the developer objects and binds them to\ncontrols in the drawer.\n\nThe most notable feature the 'debug' version exposes is the concept of endpoints. Using the spinner\nat the top of the drawer, you can change the endpoint to which the app communicates. We also expose\na false endpoint named \"Mock Mode\" which simulates an in-memory server inside the app. This \"Mock\nMode\" eases manual testing and also provides a static set of data to write instrumentation tests\nagainst.\n\n\"Mock Mode\" can be queried when modules are configuring their dependencies which is what allows\nsimulating the remote server in-memory.\n```java\n@Singleton class MockFoo() {\n  @Inject MockFoo() {}\n  // ...\n}\n```\n```java\n@Provides @Singleton Foo provideFoo(@IsMockMode boolean isMockMode, MockFoo mockFoo) {\n  return isMockMode ? return mockFoo : new RealFoo();\n}\n```\nSee `DebugDataModule` and `DebugApiModule` to see this in action in the real app.\n\nThe mock implementations of these types are some of those injected into the `DebugViewContainer` for\nbinding in the drawer. This allows us to do things like control their fake network behavior and\nalter their behavior.\n\nIn order to keep the shared state which represents the server-side data we use a `ServerDatabase`\nsingleton. At present this is only done with a combination of in-memory collections and images in\nthe `debug/assets/`. In a more complex app you could even use a full database. This class is\ninjected into each mock service which uses its methods to query and mutate state\n(e.g., `MockGalleryService`).\n\n![Debug drawer](u2020.gif)\n\n\n\nLibraries\n---------\n\n * Dagger - http://square.github.io/dagger\n * ButterKnife - http://jakewharton.github.io/butterknife\n * Retrofit - http://square.github.io/retrofit\n * Moshi - https://github.com/square/moshi\n * Picasso - http://square.github.io/picasso\n * OkHttp - http://square.github.io/okhttp\n * RxJava - https://github.com/ReactiveX/RxJava\n * Timber - http://github.com/JakeWharton/timber\n * Madge - http://github.com/JakeWharton/madge\n * ProcessPhoenix - https://github.com/JakeWharton/ProcessPhoenix\n * Scalpel - http://github.com/JakeWharton/scalpel\n * LeakCanary - http://github.com/square/leakcanary\n * Telescope - https://github.com/mattprecious/telescope\n\n\n\nTo Do\n-----\n\n * Something with animations to showcase animation control.\n * Network errors probably crash the app.\n * Add another part of the app other than 'trending' so we can demo child graphs.\n\n\n\nLicense\n-------\n\n    Copyright 2014 Jake Wharton\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n\n [video]: https://www.youtube.com/watch?v=0XHx9jtxIxU\n [slides]: https://speakerdeck.com/jakewharton/android-apps-with-dagger-devoxx-2013\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJakeWharton%2Fu2020","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJakeWharton%2Fu2020","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJakeWharton%2Fu2020/lists"}