Hilt原理分析三(xxx_Factory的作用)

简介: xxx_Factory的作用

系列文章

上一篇文章的末尾,提到了ApplicationModel_Factory这个类,当时在Application实现依赖注入的时候并没有用到生成的这个类,就没有继续介绍了,这篇我们就来了解下。

在Activity中实现依赖注入

因为在Application中依赖注入不会用到这个ApplicationModel_Factory,所以看下在Activity中实现依赖注入会不会用到ApplicationModel_Factory,为了更贴近语义,将ApplicationModel修改为ActivityModel,然后注入到Activity中,代码如下

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var model: ActivityModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        model.doSomething()
    }
}

编译运行下,打印的日志如下

290215b130ed3bfaecfde6de1cba4da.png

再看下编译后生成的文件,如下

6ec0240dc5ea77f0a5d77dff02c162a.png

可以看到这里新生成了两个文件,Hilt也是通过这两个文件实现Activity中的依赖注入的,下面通过这两个文件来了解下Hilt在Activity实现依赖注入的原理。

Hilt_MainActivity分析

通过前面两篇的内容可以知道,MainActivity编译后会继承至Hilt_MainActivity,看下Hilt_MainActivity代码

9ca6990bf8412340a7e8c696bd3179a.png

从上面的截图中可以看到,通过Hilt_MainActivity的构造方法会注册一个监听,当这个类与Context关联时会收到回调,然后继续调用inject方法,inject方法的代码如下

e9f2246c4a38f3aa6437356d8ebff4c.png

因为inject方法调用的方法会较多,这里就画出调用的时序图,重要的地方再讲下代码,部分时序图如下

b09486d4c0bbf2c7192302298879e82.png

这里看下时序图上的getViewModelProvider方法的代码,如下

private ViewModelProvider getViewModelProvider(
      ViewModelStoreOwner owner, Context context) {
    return new ViewModelProvider(
        owner,
        new ViewModelProvider.Factory() {
          @NonNull
          @Override
          @SuppressWarnings("unchecked")
          public <T extends ViewModel> T create(@NonNull Class<T> aClass) {
            ActivityRetainedComponent component =
                EntryPointAccessors.fromApplication(
                    context, ActivityRetainedComponentBuilderEntryPoint.class)
                    .retainedComponentBuilder()
                    .build();
            return (T) new ActivityRetainedComponentViewModel(component);
          }
        });
  }

可以看到这个方法创建了ViewModelProvider类,想必看到这里会意识到这个类与ViewModel有关,好了,先跟到这里。

再回到上面时序图上generatedComponent方法

023cfec1255b895b95b1be36b255838.png

这个方法的代码如下

9a4cea93106be130426dc711ae14910.png

上面的时序图是顺着componentManager方法跟下去的画的,这次来跟下generatedComponent方法,时序图如下

361b42217a66f95f3d789b19ce65f0b.png

这个时序图有两个地方需要注意下,如下图

0951440fd374d57d57276476e3da7c6.png

第一处方法的代码如下

54285a0998aca4bca478776f5f7af3c.png

重点是红框内的内容,先看下

EntryPoints.get(         activityRetainedComponentManager, ActivityComponentBuilderEntryPoint.class)

这段代码,get方法的内容如下

3bbb3cb4161b68747d3a792a08f7a9e.png

这段代码要留意一下,在后面代码执行的时候还会调用到这里,只是参数component不同,这里就不具体的分析了,继续看从这里跟下去的时序图,如下

7669d69acafecc62f5c0e43e76b567a.png

这里需要说明一下,时序图上面的ARComponentManager是ActivityRetainedComponentManager,为了方便画时序图就缩写了一下。

继续看下2处的代码,如下

7c8ab22da13092c16e8fe1d7fec5b1c.png

这里的viewModelProviderget方法,最终会调用到下面的方法

8750daae529c7a349bfc18beb53566b.png

最后调用到红框标记的地方,看到这里有没有感觉mFactory.create方法似曾相识,如果忘记的话,这里我再贴一下代码,帮助回忆下前面内容

7f321ad0966ea627bb47c11a22e8ee8.png

没错,这里就调用了文章前面跟到crate方法,好了,这里就可以继续往下看create方法的代码了,先看下

EntryPointAccessors.fromApplication(
                    context, ActivityRetainedComponentBuilderEntryPoint.class)

这段代码做了什么,fromApplication方法代码如下

0286607a7839ea88b74378322ac89ff.png

这里又调用了EntryPointsget方法,前面已经贴过代码了,这里就不看里面的代码了。这段代码调用后返回的对象是DaggerMyApplication_HiltComponents_SingletonC实例,后面分析就简单了,大家自己跟下就行,最终create方法执行完,返回的是ActivityRetainedCImpl对象。

好了,还记得我们现在是从哪里跟下来的吗?是从下面的方法,红框内的代码得到的ActivityRetainedCImpl对象,

94b641f44e88661887efec936862099.png

然后这个方法调用完,返回的是ActivityCImpl对象。好了,到这里终于快结束了,到这里我们只分析完了Hilt_MainActivity类的inject方法的前半部分

25fbe07ba028e8b97ae613722c83813.png

接着就是调用了ActivityRetainedCImplinjectMianActivity方法,代码如下

20ef4899c3573426e2daeb5b206c85f.png

最后调用到

MainActivity_MembersInjector.injectModel(instance, new ActivityModel());

这句代码。injectModel的代码如下

cf2d63f9e3ee7a47b68f7abf28e29ac.png

好了,这里就把ActivityModel注入到了MainActivity中。

纳尼,好像不对,这里还是没有解释生成的ActivityModel_Factory类的作用呀!是呀,还是没有发现ActivityModel_Factory类的作用呀,想要发现ActivityModel_Factory类的作用,还需要稍微修改下代码,新建Activity2Model

4cc251ee6ec0f152ae0d9bca07a887d.png

里面的代码如下

8d42f46ae665c2bd447b13ba07930a8.png

在修改ActivityModel类中的代码如下

3707615ae5fccbf9f069c31c2082a90.png

好了,现在再来看ActivityRetainedCImplinjectMianActivity方法的代码

1de8df6cc0d7b821282dfd5c54683d7.png

可以发现injectMainActivity2中的代码和前面的已经不一样了,好,继续往下跟,看下和以前不一样的地方,就是

activityModel的代码

0710bccd18f262b227573a7509d93b6.png

好了,总算找到了ActivityModel_Factory了,到这里也就知道为什么Hilt会为我们生成xxx_Factory类了。

总结

文章首先是分析了Hilt_MainActivity,发现最后和Hilt_MyApplication一样会走到DaggerMyApplication_HiltComponents_SingletonC类中,最后调用到ActivityCImpl类中的injectMainActivity方法实现依赖注入,然后由分析了一下为什么Hilt会生成xxx_Factory类,以及它的作用。文章只讲解了重要的代码,如果有不理解的地方可以跟着文章中的时序图自己分析下,多分析分析,就会理解了。


相关文章
|
Linux 数据安全/隐私保护 Windows
Linux vsFTPd服务详解——本地用户登录实战
Linux vsFTPd服务详解——本地用户登录实战
749 2
|
缓存 API Android开发
安卓现代化开发系列——传世不朽ViewModel
安卓现代化开发系列——传世不朽ViewModel
587 0
|
存储 监控 安全
天天在都在谈的S3协议到底是什么?一文带你了解S3背后的故事
S3的诞生绝不是偶然,是数据的爆炸增长和技术的不断推进的结果,国外用亚马逊、谷歌云等支持S3协议的比较多,国内用阿里云、腾讯云、华为云的比较多。
6090 1
天天在都在谈的S3协议到底是什么?一文带你了解S3背后的故事
|
3月前
|
人工智能 缓存 数据可视化
Claude Code换脑升级!DeepSeek V4-Pro接入、性能实测与核心问题排查手册
在AI编程工具领域,Claude Code凭借强大的任务执行、工具调用与工程化能力,成为开发者与自动化运维的核心效率工具。但原生模型存在成本高、账号稳定性波动等问题,寻找兼容、稳定、高性价比的替代方案成为刚需。DeepSeek V4-Pro作为新一代高性能大模型,原生兼容Anthropic API协议,无需代理即可无缝驱动Claude Code,且在任务执行、复杂推理、长上下文处理上表现优异,成本仅为原生高阶模型的七分之一左右。
2158 1
|
算法 计算机视觉 Python
DSP技术在音频处理中的创新与实践
DSP技术在音频处理中的创新与实践
547 2
|
存储 监控 测试技术
交换机性能指标全解析:选择最佳交换机的实用指南
【8月更文挑战第22天】交换机是网络的核心组件,选型关乎网络性能与稳定性。主要考量包括端口数量与速度、背板带宽、转发率、MAC地址表大小、管理功能、QoS支持、冗余电源、堆叠能力和PoE支持等。购买时应根据网络规模与预算选择知名品牌和型号,考虑端口配置、管理特性、安全性和扩展性,并进行性能测试与兼容性验证。
1931 1
|
Android开发
Dagger Hilt - ViewModel的依赖注入及实现原理
Dagger Hilt VIewModel 依赖注入的原理
925 0
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
1164 18
|
机器学习/深度学习 自然语言处理 搜索推荐
LangChain在个性化内容生成中的实践
【8月更文第3天】随着人工智能技术的发展,个性化内容生成已经成为许多应用的核心竞争力。LangChain 是一种开源框架,旨在简化语言模型的应用开发,尤其是针对自然语言处理任务。本文将探讨 LangChain 如何帮助开发者根据用户的偏好生成定制化的内容,从挑战到实践策略,再到具体的案例分析和技术实现。
1234 1
|
Linux 开发工具 C++
Visual Studio 和 VSCode 哪个更好
Visual Studio(VS)与Visual Studio Code(VSCode)作为微软旗下的两款开发工具,各自在软件开发领域占据重要位置。VS作为功能全面的集成开发环境,适合企业级大型项目开发;而VSCode则以其轻量级、灵活性和强大的扩展性,赢得了广大开发者的青睐。
2776 0

热门文章

最新文章