当前位置:网站首页>Andorid Jetpack Hilt
Andorid Jetpack Hilt
2022-06-29 15:40:00 【Lighthouse @kuaidao】
Preface
Ben blog It's learning Hilt After the official documents , Notes taken by hand , Welcome to discuss and exchange Hilt usage
Hilt Used annotations and classes
| annotation | explain |
|---|---|
| @HiltAndroidApp | @HiltAndroidApp Will trigger Hilt Code generation operations for , The generated code includes a base class for the application , The base class acts as an application level dependency container |
| @EntryPoint | “hilt Manage code and non hilt Manage the boundaries between code. It is the first time code enters Hilt The location of the graph of the managed objects ” |
| @InstallIn | Specify the component in which to install the entry point |
| @AndroidEntryPoint | Act as component holder |
| EntryPointAccessors | Access the entry point tool |
| @ApplicationContext | Predefined qualifiers |
| @ActivityContext | Predefined qualifiers |
| DFM ( Dynamic function module ) | |
| @Inject | Provide dependent objects |
| @WorkerInject | WorkManager Inject |
| @Assisted | WorkManager Inject |
| @Singleton | Limit scope |
Hilt modular @Module [email protected] notes
solve the problem :
1. You cannot inject an interface through a constructor
2. You cannot inject a type that is not yours through a constructor ( Classes of external libraries )
Solutions :
@Module The annotations Hilt Module class @Binds The annotated function will tell Hilt How to provide some types of instances
Example :
@Module
@InstallIn(ActivityComponent::class) Rely on projects to inject all extensions from ActivityComponent Subclasses of
abstract class AnalyticsModule {
@Binds
abstract fun bindAnalyticsService(
analyticsServiceImpl: AnalyticsServiceImpl
): AnalyticsService
}
explain : stay Hilt Create a module with @Binds Annotated abstract functions (@Binds The notes will tell Hilt Which implementation to use when you need to provide an instance of the interface ),
with @Binds The function of will give Hilt Provide the following information : The return type of the function tells Hilt Function provides an instance of which interface .
Function arguments tell Hilt What kind of implementation to provide .
Use @Provides Injection case
solve the problem :
1.Retrofit、OkHttpClient、Room Or you have to use the builder pattern to create an instance , Nor can constructor function injection be used
Solutions :
@Provides The annotation function will send a message to Hilt Provide the following information
- The return type of the function tells Hilt Which type of instance does the function provide .
- Function arguments tell Hilt Dependencies of the corresponding type .
- The body of the function tells Hilt How to provide instances of corresponding types . Whenever you need to provide an instance of this type ,Hilt Will execute the body of the function .
Example :
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {
@Provides
fun provideAnalyticsService(
// Potential dependencies of this type
): AnalyticsService {
return Retrofit.Builder()
.baseUrl("https://example.com")
.build()
.create(AnalyticsService::class.java)
}
}
Provide multiple bindings for the same type
solve the problem :
1. Provide different implementations of the same type in the form of dependencies
Solutions :
You can use qualifiers to define multiple bindings for the same type
A qualifier is a comment , When multiple bindings are defined for a type , You can use it to identify a specific binding of this type .
Sample steps :
1. The definition should be as follows @Binds or @Provides Method to add a qualifier for the comment
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient
@Module
@InstallIn(ApplicationComponent::class)
object NetworkModule {
@AuthInterceptorOkHttpClient
@Provides
fun provideAuthInterceptorOkHttpClient(
authInterceptor: AuthInterceptor
): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.build()
}
@OtherInterceptorOkHttpClient
@Provides
fun provideOtherInterceptorOkHttpClient(
otherInterceptor: OtherInterceptor
): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(otherInterceptor)
.build()
}
}
Invoke the sample :
In system class , In the custom class ,hiltModule in
// As a dependency of another class.
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {
@Provides
fun provideAnalyticsService(
@AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
): AnalyticsService {
return Retrofit.Builder()
.baseUrl("https://example.com")
.client(okHttpClient)
.build()
.create(AnalyticsService::class.java)
}
}
// As a dependency of a constructor-injected class.
class ExampleServiceImpl @Inject constructor(
@AuthInterceptorOkHttpClient private val okHttpClient: OkHttpClient
) : ...
// At field injection.
@AndroidEntryPoint
class ExampleActivity: AppCompatActivity() {
@AuthInterceptorOkHttpClient
@Inject lateinit var okHttpClient: OkHttpClient
}
Best practices :
If you add a qualifier to a type @Qualifier, Qualifiers should be added to all possible ways of providing this dependency . Avoid omitting dependencies that cause injection errors .
@Inject Inform the injection position ,@ActivityContext Predefined qualifiers , By default, the system provides
java Annotations can be applied to formal parameters (PARAMETER,) and local_paramter The local variable
by Android System classes generate default components
@InstallIn Components that can be associated
| ApplicationComponent | Application |
| ActivityRetainedComponent | ViewModel |
| ActivityComponent | Activity |
| FragmentComponent | Fragment |
| ViewComponent | View |
| ViewWithFragmentComponent | with @WithFragmentBindings The annotations View |
| ServiceComponent | Service |
Example :
@Module
@InstallIn(xxxComponent::class)
class xxxModule{
@Binds
or
@Provides
}
because Hilt Directly from ApplicationComponent Into the broadcast receiver .
Scope
solve the problem :
- Limit the use of dependencies , Dependency is initialized only once within limits . Avoid duplicate creation and waste resources
- Dependency is only valid in one scope .
Solutions :
The first two need to focus on ,hilt Scope provided .
| Application | ApplicationComponent | @Singleton |
| View Model | ActivityRetainedComponent | @ActivityRetainedScope |
| Activity | ActivityComponent | @ActivityScoped |
| Fragment | FragmentComponent | @FragmentScoped |
| View | ViewComponent | @ViewScoped |
| Service | ServiceComponent | @ServiceScoped |
hilt Classes that support injection ,Android class , Four components viewModel,View
The above describes the objects that cannot be injected into the constructor or other objects that do not belong to the third-party class diagram of the application , adopt build To build . The following is about Hilt Injection of dependencies into unsupported classes
For unsupported types , Define the entry point binding component form , Then retrieve the component through the class , Get the type in the component
such as :ContentProvider To be used in Hilt Provided dependencies
solve the problem :
- Unsupported classes want to use hilt Provide dependent objects
Solutions : Visit the entry point
- Use @EntryPoint notes @InstallIn( Install class ), Define interfaces and object references to be provided . Declared in an unsupported class
Example
class ExampleContentProvider : ContentProvider() {
@EntryPoint
@InstallIn(ApplicationComponent::class)
interface ExampleContentProviderEntryPoint {
fun analyticsService(): AnalyticsService
}
...
}
Used in multi module applications Hilt
DFM How to set dependency , By setting the entry point in the main module ( The direction of dependency is opposite to that of non dynamic module settings ), Set up Dagger The module depends on the main module function point Put in the function module , Function modules use drgger To build .
Add dependency injection manually
- First, create all the dependent objects in a class , And put them together for use
- In order to reuse , Extract the assembled logic into the service locator for global unified management
- Different object dependencies need to be created for different interface processes . Put the creation of the object into the service locator , And create factory methods to provide external objects
- For different business processes , You need to create different dependent containers , And binding interface (Activity/Fragment) Life cycle , stay onCreate() Create in the corresponding Destroy() The destruction
- In special cases, it is necessary to keep the object state after configuration changes , You need to use a state container , Lifecycle binding depends on containers and ui Life cycle management tools are recommended for interface components LifeCycle
advantage :
- Dependency injection is important for creating extensible and testable Android Application is a suitable technology
- Use containers as a way to share instances of various classes in different parts of the application , And use the factory to create the centralized location of each class instance
- Manual dependency injection requires you to manually construct each class and its dependencies , And reuse and manage dependencies with containers and factories .
shortcoming :
- Applications get bigger , More processes , Different interface processes need to maintain different container creation and destruction , Maintenance of plant methods .
- Will write a lot of boilerplate code , It's easy to make a mistake , Improper lifecycle management can lead to minor errors and memory leaks
Manual injection requires writing template code , Multiple modules rely on top-level modules to build objects , Need to depend on different sub modules . Dependency management , Dependency scope management , Rely on Lifecycle Management , Dependent reuse . You need to consider
problem
- For example , I have a class A, I want to inject classes through constructors or by passing arguments B What to do ?
- For example , The program code needs an external library Retrofit perhaps OkHttp Object or interface ( Control flip ), How to declare dependencies .
summary :
hilt be based on Dagger Provide a set of standard dependency injection practices ,Hilt To optimize the Dagger The function of dependency injection , Reduce the writing of sample code , There are two main ways of dependency injection , Constructor injection is the most commonly used , Parameter injection takes precedence over constructor injection , For interfaces , Third party tool libraries cannot modify the dependency injection of the source code , Need to create Hilt modular , And use @Module @Installin( Depending on the installed class ::class),@Provider(sdk Of Builder structure ),@Binds( Interface , abstract class ) Annotations solve the problem of dependency passing .
hilt usage xmind Brain map 
1. Hilt Introduction to Chinese
2. Dagger Introduction to Chinese
边栏推荐
- 服务器的数据库连不上了【服务已起、防火墙已关、端口已开、netlent 端口不通】
- kotlin 注解声明与使用
- Northwestern Polytechnic University attacked by overseas e-mail
- GWD:基于高斯Wasserstein距离的旋转目标检测 | ICML 2021
- 极化SAR地表分类
- message from server: “Host ‘xxxxxx‘ is blocked because of many connection errors; unblock with ‘m
- 无意发现的【TiDB缓存表】,竟能解决读写热点问题
- 上次给我们发福利的 TDesign ,今天讲讲它的开源故事
- 12.UDP协议-bite
- 雷达基本组成
猜你喜欢

Lumiprobe reactive dye - amino dye: cyanine 5 amine

Building SQL statements in Excel

Lumiprobe deoxyribonucleic acid phosphate CpG 1000 solid carrier

File common tool class, stream related application (record)

明德扬XILINX-K7-325T/410T核心板数据手册

Flink SQL task taskmanager memory settings

Review of digital image processing

Create an API rapid development platform, awesome!

在shop工程中,实现一个菜单(增删改查)

Mingdeyang xilinx-k7-325t/410t core board data manual
随机推荐
京东健康回应拟以 3.554 亿美元收购京东资产:与宠物健康产品品类相关
List集合详细讲解
Scroll,你玩明白了嘛?
NFS configuring file mapping between two hosts
"Game engine shallow in shallow out" 98 Substancepainer plug-in development
Neural network for remote sensing image processing
postgresql源码学习(24)—— 事务日志⑤-日志写入WAL Buffer
Northwestern Polytechnic University attacked by overseas e-mail
Basic composition of radar
Google 软件版本经历周期
ImgUtil 图片处理工具类,文字提取,图片水印
深度学习网络的训练方式
postgresql源码学习(25)—— 事务日志⑥-等待日志写入完成
MySQL开发规范.pdf
分页sql(rownum、row_number、dense_rank、rank)
Why MySQL chooses b+ tree to store indexes
For example, the visual appeal of the live broadcast of NBA Finals can be seen like this?
极化SAR几种成像模式
Scroll, do you understand?
深入理解 Promise 之手把手教你写一版