You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/** * A generated base class to be extended by the @dagger.hilt.android.HiltAndroidApp annotated class. If using the Gradle plugin, this is swapped as the base class via bytecode transformation. */abstractclassHilt_AppextendsApplicationimplementsGeneratedComponentManagerHolder {
privatefinalApplicationComponentManagercomponentManager = newApplicationComponentManager(newComponentSupplier() {
@OverridepublicObjectget() {
returnDaggerApp_HiltComponents_SingletonC.builder()
.applicationContextModule(newApplicationContextModule(Hilt_App.this))
.build();
}
});
@OverridepublicfinalApplicationComponentManagercomponentManager() {
returncomponentManager;
}
@OverridepublicfinalObjectgeneratedComponent() {
returnthis.componentManager().generatedComponent();
}
@CallSuper@OverridepublicvoidonCreate() {
// This is a known unsafe cast, but is safe in the only correct use case:// App extends Hilt_App
((App_GeneratedInjector) generatedComponent()).injectApp(UnsafeCasts.<App>unsafeCast(this));
super.onCreate();
}
}
前言
在完成了初步的学习和一些验证工作及可行性实验代码以后。正式开始在项目中尝试使用Hilt,以实践带动学习。最近在开发过程中遇到了些问题,在解决过程中对Hilt的注入原理又有了更深一点的理解。
@Inject的困惑之谜
首先我在Application中的代码是这样的
launcherManager通过外部注入获取,结果运行直接出错,launcherManager为null。注入失败了?
有一些奇怪,接下来尝试到MainActivity
注入成功了。奇怪了,都是EntryPoint。话说总入口还比Activity的EntryPoint要高级啊,没道理啊
终于一个尝试改动修复了HiltAndroidApp注入失败的问题。(我承认运气一直不错。偶然的改动往往能撞到真相,算是瞎猫碰死耗子吧)
改动如下
就是说只要在super.onCreate();之后再去调用launcherManager就行,这时候launcherManager已经被注入了。
打破沙锅问到底
显然是 super.onCreate();的时候launcherManager被执行了注入操作。但是Application类作为基类,也翻不到执行相关代码的地方啊。难道执行了什么魔法?
进一步探索,通过AS的Find Usage的菜单,翻到了Hilt自动生成的App_MembersInjector类,这里自动执行了laucherManager注入
代码片段(带删减)
在onCreate方法中实现了App类型的字段注入
代码片段
已经很接近真相了,通过debug来验证下
在injectApp这行代码加上断点。
在断点命中后,查看堆栈,发现是在App.java的23line调用的就是super.onCreate();
很神奇吧,就是说Hilt_App是App的真父类,而Application其实是爷爷。
狸猫换太子,Hilt_App就是玩了一把适配器模式,让大家都毫无知觉
幕后的App_HiltComponents
通过前面的Hilt_App的代码我们可以看到componentManager是加载了App_HiltComponents的工厂类型。我们在Hilt的幕后组件原理藏在这里。所以说Hilt是Dragger的Plus版本
一网打尽
就是MainActivity的影子父类
Hilt_MainActivity会通过Application找到activityComponent这层的组件完成注入工作。
可以看到是在onContextAvailable的回调中执行了注入操作
MainActivity_MembersInjector
MainActivity具体的注入方法
总结
@HiltAndroidApp和@androidentrypoint都有影子父类
影子父类通过适配模式存在
影子父类会加载componentManager,component就是Dragger的Component
Component根据安卓的组件分成很多层
影子父类会执行对象注入的具体工作
注入时机非常巧妙,其中Application是在执行onCreate时执行,而Activity是在ContextAvailable以后。反正绝对不是构造函数,大家在使用中一定要注意。
老规矩,以后补图,完
The text was updated successfully, but these errors were encountered: