hilt
Hilt Skill
Comprehensive assistance with hilt development, generated from official documentation.
When to Use This Skill
This skill should be triggered when:
- Working with hilt
- Asking about hilt features or APIs
- Implementing hilt solutions
- Debugging hilt code
- Learning hilt best practices
Quick Reference
Common Patterns
Pattern 1: Hilt Benefits Gradle Setup Quick Start Core APIs → Components → Hilt Application → Android Entry Points → View Models → Modules → Entry Points → Custom Components Testing → Testing overview → Robolectric testing → Instrumentation testing → Early Entry Points Migration → Guide → Custom inject → Optional inject → Scope aliases Flags Creating Extensions Design Decisions → Design overview → Testing philosophy → Monolithic components → Subcomponents The @EarlyEntryPoint annotation provides an escape hatch when a Hilt entry point needs to be created before the singleton component is available in a Hilt test. Note that, although @EarlyEntryPoint and EarlyEntryPoints are mostly used in production code, they only have an effect during Hilt tests. In production, these entry points behave the same as @EntryPoint and EntryPoints, respectively. Background In a Hilt test, the singleton component’s lifetime is scoped to the lifetime of a test case rather than the lifetime of the Application. This is useful to prevent leaking state across test cases, but it makes it impossible to access entry points from a component outside of a test case. To get a better understanding of why/when this becomes an issue, let’s look at a typical lifecycle of an Android Gradle instrumentation test. # Typical Application lifecycle during an Android Gradle instrumentation test - Application created - Application.onCreate() called - Test1 created - SingletonComponent created - testCase1() called - Test1 created - SingletonComponent created - testCase2() called ... - Test2 created - SingletonComponent created - testCase1() called - Test2 created - SingletonComponent created - testCase2() called ... - Application destroyed As the lifecycle above shows, Application#onCreate() is called before any SingletonComponent can be created, so calling an entry point from Application#onCreate() is not possible. (For the same reason, there are similar issues with calling entry points from ContentProvider#onCreate()). While these cases should be rare, sometimes they are unavoidable. This is where @EarlyEntryPoint comes in. Usage Annotating an entry point with @EarlyEntryPoint instead of @EntryPoint allows the entry point to be called at any point during the lifecyle of a test application. (Note that an @EarlyEntryPoint can only be installed in the SingletonComponent). For example: Java Kotlin @EarlyEntryPoint @InstallIn(SingletonComponent.class) public interface FooEntryPoint { Foo foo(); } @EarlyEntryPoint @InstallIn(SingletonComponent::class) interface FooEntryPoint { fun foo(): Foo } Once annotated with @EarlyEntryPoint, all usages of the entry point must go through EarlyEntryPoints#get() (rather than EntryPoints#get() ) to get an instance of the entry point. This requirement makes it clear at the call site which component will be used during a Hilt test. For example: Java Kotlin // A base application used in a Hilt test that injects objects in onCreate public abstract class BaseTestApplication extends Application { @Override public void onCreate() { super.onCreate(); // Entry points annotated with @EarlyEntryPoint must use // EarlyEntryPoints rather than EntryPoints. foo = EarlyEntryPoints.get(this, FooEntryPoint.class).foo(); } } // A base application used in a Hilt test that injects objects in onCreate public abstract class BaseTestApplication: Application { override fun onCreate() { super.onCreate() // Entry points annotated with @EarlyEntryPoint must use // EarlyEntryPoints rather than EntryPoints. foo = EarlyEntryPoints.get(this, FooEntryPoint::class).foo() } } Caveats The component used with EarlyEntryPoints does not share any state with the singleton component used for a given test case. Even @Singleton scoped bindings will not be shared. The component used with EarlyEntryPoints does not have access to any test-specific bindings (i.e. bindings created within a specific test class such as @BindValue or a nested module). Finally, the component used with EarlyEntryPoints lives for the lifetime of the application, so it can leak state across multiple test cases (e.g. in Android Gradle instrumentation tests). When not to use EarlyEntryPoint Most usages of @EarlyEntryPoint are needed to allow calling entry points from within Application#onCreate() or ContentProvider#onCreate(). However, before switching to @EarlyEntryPoint, try the alternatives listed below. Entry points for Application getter methods If the entry point is used to initialize a field that will later be returned in a getter method, consider removing the field and getter method and replacing it with a @Singleton scoped binding that other classes can inject directly rather than going through the application class. If the getter method is required (e.g. the application must extend an interface that requires it to be overriden) then try replacing the field with a @Singleton scoped binding and calling EntryPoints.get() lazily from the getter method. Entry points for initialization/configuration If the entry point is used to perform initialization/configuration (e.g. setting up a logger or prefetching data) then first consider whether this work is necessary for your tests. Most tests, e.g. tests for activities and fragments should not be dependent on this initialization to work properly, since activities and fragments should generally be designed to be reusable in other applications. If your test needs the initialization/configuration, consider whether it’s okay to only run the initialization/configuration once and share any state of that run between tests. If that’s not okay, then you may need to consider moving the logic into a TestRule instead.
More from tianguzhe/zsh-config
koin
Koin dependency injection framework for Kotlin. Use for Kotlin DI, Android development, Ktor backend, Compose Multiplatform, dependency injection patterns, and module definitions.
17google-play-billing
Google Play Billing Library for Android in-app purchases and subscriptions. Use for implementing IAP, managing products, handling purchases, validating transactions, and subscription management.
10ace-serena-collaborator
|
9codex-collaborator
Codex MCP 协作流程。触发场景:(1) 新功能开发 (2) 重构 (3) 复杂业务逻辑 (4) 代码审查。提供三阶段协作:需求分析→原型获取→审查,强调批判性思考与只读安全。
8sequential-thinking
Use when complex problems require systematic step-by-step reasoning with ability to revise thoughts, branch into alternative approaches, or dynamically adjust scope. Ideal for multi-stage analysis, design planning, problem decomposition, or tasks with initially unclear scope.
7frontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
5