1. Basic Introduction:

  • Field injection: Hilt needs to know how to provide instances of the necessary dependencies from the corresponding Component.
  • Binding: An instance of a type is used as a dependency to provide the required information.

2. Notes:

@ HiltAndroidApp:

  • All applications that use Hilt must include an Application class annotated with @hiltAndroidApp.
  • The @HiltAndroidApp triggers code generation for Hilt, which includes a base class for the application that acts as an application-level dependency container.
  • The generated Hilt component is attached to the Application object’s life cycle and provides dependencies for it.
  • In addition, it is the parent of the application, which means that other components can access the dependencies it provides.
@HiltAndroidApp
class MyApplication:Application() {}Copy the code

@ AndroidEntryPoint:

  • Once the Hilt is set up in the Application class and the application-level component is available, AndroidEntryPoint generates a separate Hilt Component for each Android class in the project (Activity, Fragment, Service, View, BroadcastReceiver). These components can receive dependencies from their respective parent classes.
  • If you annotate an Android class using @AndroidEntryPoint, you must also annotate the Android classes that depend on that class. For example, if you add annotations to a Fragment, you must also add annotations to all activities that use that Fragment.
  • Hilt only supports activities that extend ComponentActivity, such as AppCompatActivity.
  • Hilt only supports fragments that extend Androidx. Fragment.

@ Inject:

  • Fields injected by Hilt cannot be private.
  • Used on property fields or constructors to inject fields or provide constructor class instances.

@ InstallIn:

  • Declare in which Component the annotated target class should be included when Hilt generates a Component (such as an ActivityComponent is automatically generated).
  • Can only be used in classes annotated with @Module or @entryPoint.
@Module
@InstallIn(ActivityComponent::class)  / / tell Hilt the module belongs to Component, ActivityComponent Hilt is defined
interface MainModule {
    @Binds
    fun bindEngine(chinaEngine:ChinaEngine):Engine
}
Copy the code

Component in Hilt:

3.1 Basic Introduction

  • For each Android class (Activity, Fragment, Service, View, BroadcastReceiver) from which field injection can be performed, there needs to be an associated Hilt component that you can reference with the @installin annotation.
  • Each Hilt component is responsible for injecting its bindings into the corresponding Android target classes (Activity, Fragment, Service, View, BroadcastReceiver) using the @Inject annotation.

3.2 Components provided by Hilt by default:

Hilt components The object for which the injector is oriented
ApplicationComponent Application
ActivityRetainedComponent ViewModel
ActivityComponent Activity
FragmentComponent Fragment
ViewComponent View
ViewWithFragmentComponent Views with @WithFragmentBindings annotations
ServiceComponent Service
  • Hilt does not generate components for the broadcast receiver because Hilt injects the broadcast receiver directly from ApplicationComponent.

3.3 Default component life cycle:

Generated components Create time Destruction of the timing
ApplicationComponent Application#onCreate() Application#onDestroy()
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ActivityComponent Activity#onCreate() Activity#onDestroy()
FragmentComponent Fragment#onAttach() Fragment#onDestroy()
ViewComponent View#super() View destruction
ViewWithFragmentComponent View#super() View destruction
ServiceComponent Service#onCreate() Service#onDestroy()
  • ActivityRetainedComponent still exist after configuration changes, so it is in the first call Activity# onCreate () is created, in the last call Activity# onDestroy () is destroyed.

3.4 Component scope:

  • By default, all bindings in Hilt are unscoped. This means that each time a request binding is applied, Hilt creates a new instance of the required type.
  • It can be costly to limit the scope of a binding to a component because the supplied object remains in memory co-existing with an instance until the component is destroyed. Use scoped bindings as little as possible in your application.
  • If the internal state of the binding requires that the same instance be used within a scope, or if the binding is expensive to create, scoping the binding to a component is appropriate.
Android class Generated components scope
Application ApplicationComponent @Singleton
View Model ActivityRetainedComponent @ActivityRetainedScope
Activity ActivityComponent @ActivityScoped
Fragment FragmentComponent @FragmentScoped
View ViewComponent @ViewScoped
Views with @WithFragmentBindings annotations ViewWithFragmentComponent @ViewScoped
Service ServiceComponent @ServiceScoped

3.5 Hierarchical dependency structure of components:

  • Once a Module Module is installed into a component, a binding provision in that Module can be used as a dependency for other bindings in that component, or for other bindings in any child component under that component in the component hierarchy.

3.6. The default binding instance provided by the component:

  • Each Hilt component comes with a set of default binding instances that Hilt can inject as dependencies into your own custom binding.
  • Note that these bindings correspond to regular Activity and Fragment types, not to any specific subclass. This is because Hilt uses a single Activity component definition to inject all activities. Each Activity has a different instance of this component.
Android components The default binding
ApplicationComponent Application
ActivityRetainedComponent Application
ActivityComponent The Application and the Activity
FragmentComponent Application, Activity, and Fragment
ViewComponent Application, Activity, and View
ViewWithFragmentComponent Application, Activity, Fragment, and View
ServiceComponent The Application and Service

4. Hilt Module:

  • Sometimes, types cannot be injected through constructors, and in these cases, you can use the Hilt module to provide binding information to the Hilt.
  • A Hilt Module is a class annotated with @Module. Like the Dagger module, it tells Hilt how to provide instances of certain types.
  • You must annotate Hilt modules with @installin to tell Hilt which Android class each module will be used in or installed in.
  • The other uses of Module are the same as those of Dagger2. See the next article on Dagger2 usage.

Provide dependency injection in classes not supported by Hilt by default:

  • Because @AndroidEntryPoint has a limited scope, instances that use Hilt injection outside of this scope can be implemented using @EntryPoint.
  • This looks like a solution to Hilt’s standardization of Components so that users can’t add methods to them, so that they can’t provide dependencies where annotations are not available.
  • @EntryPoint:
    • Use to mark an interface as an entry point to generate the Component.
    • This annotation must be used with @installin to indicate which Component should have this entry point.
    • Hilt will make the specified component extend the interface of the annotation tag.
  // Let SingletonComponent bind the Bar instance.
  @EntryPoint
  @InstallIn(SingletonComponent.class)
  public interface FooBarInterface {
    Bar getBar(a);
  }
   
  // Get the bound Bar instance from the SingletonComponent
  Bar bar = EntryPoints.get(applicationContext, FooBarInterface.class).getBar();
Copy the code

6. Using Hilt in multi-module applications:

  • Hilt code generation operations require access to all Gradle modules that use Hilt. Gradle modules compiling Application classes need to include all Hilt modules and classes injected through constructors in their pass-through dependencies.
  • If a multi-module project consists of regular Gradle modules, you can use Hilt as described in Implementing Dependency Injection with Hilt. However, this is not the case for applications that contain dynamic functional modules (DFM).
  • In DFM, the way modules rely on each other is usually reversed. Therefore, Hilt cannot handle annotations in dynamic functional modules. You must perform dependency injection using Dagger in DFM.
  • You must use component dependencies to solve this problem with DFM. Please follow the following steps:
    • Declare an @EntryPoint interface in the APP module (or any other module that can be handled by Hilt) that has the required DFM dependencies.
    • Create a Dagger Component in the DFM module that relies on the @EntryPoint interface.
    • Use Dagger2 as usual in the DFM module.

Reference: the dagger. The dev/hilt/quick -…


To learn more, welcome to follow:

  • Blog: longyuan5. Gitee. IO /

  • Csdn:blog.csdn.net/www15750660…

  • The Denver nuggets: juejin. Cn/user / 435372…