Toothpick: a fresh approach to Dependency Injection (DI) on Android.

Toothpick: a fresh approach to Dependency Injection (DI) on Android.

You find RoboGuice simple but slow ? And you think Dagger 1 & 2 are fast but complex and bloated ? Toothpick is the best of both worlds !
Toothpick is a scope tree based, runtime but reflection free implementation of JSR 330. It is pure Java, with a special focus on Android.
Toothpick is fast (even faster than Dagger 2 in some cases!) and is simpler to use, with less boilerplate code. Its syntax is very close to Guice. It supports named dependencies, lazy dependencies, providers, and has built-in support for custom scopes. As compared to Dagger 2, Toothpick provides more powerful testing support, allowing you to leverage DI to mock dependencies using either mockito or easymock.
Its explicit scope tree helps developers to build more robust apps. It provides more fine grained control to easily implement complex user flows that span multiple activities or state preservation across configuration changes (e.g. rotations), a common issue when implementing the MVP pattern.
During this talk for experts, we will introduce Toothpick, its main features and how it compares to other DI libs. We will explain how Toothpick scopes and scope annotations can solve advanced use cases when developing Android apps.
Prerequisites: DI on Android, testing, mocking, memory leaks.



June 24, 2016


  1. Toothpick: 
 scope tree 
 Dependency Injection

  2. 2/40 About us Stéphane Nicolas Senior Android Dev at Groupon

    stephanenicolas snicolas +stephane nicolas Daniel Molinero Android Dev at Groupon dlemures +DaniLemures @D_Lemures
  3. Groupon Android Team is Hiring

  4. 4/40 Toothpick What is Toothpick? • Scope tree based Dependency

    Injection library • Full featured implementation of the JSR 330 • Runtime based, but does not use reflection. Replaced by annotation processing • Almost as fast as Dagger, even faster in some cases • As simple as Roboguice, with few rules • Advanced testing support
  5. • Introduction • TP Vs Daggers: Even sharper ! •

    Toothpick Features • Basic Injections • Scope Tree of an Android App • Configurations • Testing • Flows & Scopes • Conclusion Plan 5/40
  6. Roboguice - Runtime time DI • friendly syntax, simple •

    too slow (uses reflection) • too big (dex methods count & APK size) Why Toothpick ? Daggers - Compile time DI • Fast ! • tough syntax. Hard to use & maintain • No easy testing 6/40
  7. 7/40 Why Toothpick ? Ease of use Speed Roboguice Dagger

    Toothpick Best of both worlds
  8. 8/40 Toothpick Vs. Daggers Speed comparison

  9. 9/40 Toothpick Vs. Daggers 1000 injections • Dagger 1: 33

    ms • Dagger 2: 31 ms • Toothpick: 35 ms 6400 injections • Dagger 1: 45 ms • Dagger 2: 42 ms • Toothpick: 66 ms Speed comparison in a reasonable range TODO redo the graph for 0 injection
  10. 10/40 Toothpick Vs. Daggers Ease of use TP gains over

    Dagger 2: • Lines of Code: • No need for component interfaces • No special rules to passover stuff to sub- components • More flexible use of field / constructor injections • Less rules to learn, easier to use.
  11. Dependencies? • Snow Cone Machine. • Dependencies: Ice Machine +

    Syrup Dispenser 11/40 Basic Injection
  12. Snow Cone Machine • Dependencies: Ice Machine + Syrup Dispenser

    12/40 Basic Injection
  13. Basic Injection : @Inject Snow Cone Machine • Dependencies: Ice

    Machine + Syrup Dispenser 13/40 Specify Dependencies SnowConeMachine uses @Inject to specify its dependencies. It can use Lazy to lazily create some dependencies.
  14. Basic Injection : Scopes 14/40 Scope Instance creations take place

    inside scopes SnowConeMachine IceMachine SyrupDispenser All dependencies of the SnowConeMachine are injected.
 Transitively, all dependencies of the dependencies are created as well…
  15. Basic Injection : Scopes 15/40 Scope Injections take place inside

    scopes When we don’t have control on the creation of an entry point, we can inject its fields inside a scope. It will also create transitively all dependencies.
  16. Basic Injection : Scopes & Bindings 16/40 Scope Scopes contain

    bindings. Bindings are configured via modules. 
 IceMachine’s instance is a singleton of this scope. Module 1 Module 2 IceMachine —> new IceMachine SyrupDispenser —> LemonSyrupDispenser
  17. Basic Injection : Scopes & Bindings 17/40 Bindings describe what

    is to be injected.
 Bindings can recycle instances → Singletons. SnowConeMachine IceMachine Lemon
  18. 18/40 Scope annotations • The Ice Machine is a Singleton

    • Use @Singleton annotation or a module = Scope IceMachine
 —> new IceMachine =
  19. 19/40 Scope annotations TODO custom scope annotations. Present singleton as

    a special case.
  20. Scope tree of an Android App 20/40 Application MakeLemonCones

 Activity SyrupDispenser
 —> LemonSyrupDispenser SyrupDispenser
 —> AppleSyrupDispenser IceMachine
 —> new IceMachine IceMachine is a Singleton at the App level. SyrupDispenser is bound to different implementations in each activity scope.
  21. Scope tree of an Android App 21/40 Application IceMachine

    new IceMachine
  22. Scope tree of an Android App 22/40 Application MakeLemonCones

    When opening multiple scopes at the same time, 
 they will be children from each other, in left to right order. The last child scope is returned.
  23. 23/40 Toothpick Modules 2 Snow Cone Machines: Lemon and Apple

    Each activity will define its own scopes, that defines different bindings
  24. Scope tree of an Android App 24/40 Application Activity 2

    TP scope tree is totally extensible. It can be printed at anytime. Activity 1 Fragment 2 View 1 Fragment 1 Service 2 Service 1
  25. Configurations 25/40 TODO slide with all possible configurations

  26. Configurations 26/40 TODO slide to explain registries

  27. Configurations 27/40 Performance of Registries Vs. Reflection

  28. Testing: simple tests 28/40

  29. Testing: simple tests 29/40 Chain Junit4 
 rules Prepare m

 & stuff under test Enjoy
  30. Testing: even simpler tests 30/40

  31. Testing: Robolectric tests 31/40

  32. 32/40 Chain Junit4 
 rules override activity scope with m

    ocks from TP Testing: Robolectric tests
  33. Testing 33/40 Application MakeLemonCones
 Activity Toothpick testing offers: • both

    mockito and easymock support • create mocks with annotations • creates any scope and binds mocks into the scope • create instances and injects on demand your mocks go here
  34. Flows and scopes: MVP 34/40 Custom scope Application Activity 1

    Activity 1 MVP, keeping the presenter state • Nowadays → Retained fragments, 
 Loaders, etc. • Toothpick → Use a scope to retain 
 the instance of the Presenter
  35. Flows and scopes: MVP 35/40 Custom scopes: • are not

    related to life cycle of objects • can be associated with a scope annotation • an annotated dependency will be created in this custom scope • allow to persist state across rotations • can span across multiple activities (user flows) Custom scope Activity 2 Application Activity 1 Activity 1
  36. Flows and scopes: MVP 36/40 Define a depedency Create a

 scope annotation Annotate a 
 dependency to make it a 
 singleton of a 
 custom scope
  37. Flows and scopes: MVP 37/40 Presenter
 Scope Application Activity 1

  38. Flows and scopes: MVP 38/40 Close the scope
 of the

    activity as it dies Close the presenter
 scope as you leave this flow App Presenter Activity
  39. Flows and scopes: MVP 39/40 User flow scope Activity 3

    Application Activity 1 • User flow data • Nowadays -> Send data over and over through Intents, Database, … • Toothpick -> Use a common scope for the whole flow to keep flow related data • The data will be garbage collected as you close the scope when leaving the flow Activity 2
  40. 40/40 Conclusion • Toothpick is scope tree based DI framework

    • Fast and simple • Advanced testing support • Offers nice advanced scenarios: 
 Presenter scope, User Flow Scope, etc. Comments // Questions ?