初探Dagger2遇到的小坑
来源:互联网 发布:阿里云提供的服务 编辑:程序博客网 时间:2024/06/05 23:06
编译没错,为什么就是注入不了
//非常简单的一个活动class MainActivity : AppCompatActivity() { @Inject lateinit var a: String//待注入的变量 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerMainComponent.builder() .mainModule(MainModule()) .build() .inject(this)//注入 Log.d("=============", a)//打印看看结果 }}//提供字符串的module@Moduleclass MainModule { @Provides fun provideString(): String = "123"}@Component(modules = arrayOf(MainModule::class))interface MainComponent { fun inject(activity: Activity)}
貌似操作都没错呀,然后结果如下:
Error: lateinit property a has not been initialized所以这是为什么呢,还是看看Dagger生成的Inject方法是怎么工作的吧,说不定从这能找到答案
@Override public void inject(Activity activity) { MembersInjectors.<Activity>noOp().injectMembers(activity); }
上面就是生成的inject方法了,显然要往injectMembers里面挖
//跳进来发现这是个空方法,那就一定有他的实现类了void injectMembers(T instance);//========== 实现1 ===========@Override public void injectMembers(MainActivity instance) { if (instance == null) { throw new NullPointerException("Cannot inject members into a null reference"); } instance.a = aProvider.get(); }//========== 实现2 ===========@Override public void injectMembers(Object instance) { checkNotNull(instance); }
可以看到,实现1中就对我们要注入的字符串a进行了赋值,而实现2中只是检查了一下目标类是不是空的。而实现1的对象是这样(<Activity>noOp())才能拿到的
//正确MembersInjectors.<MainActivity>noOp().injectMembers(activity);//错误MembersInjectors.<Activity>noOp().injectMembers(activity);
也就是说我们的inject方法参数写错了,只要吧MainComopnent中inject的参数改为MainActivity就好了
@Component(modules = arrayOf(MainModule::class))interface MainComponent { fun inject(activity: MainActivity)}
再跑一下:=============: 123
为什么我的单例会报错
@Moduleclass MainModule { @Provides @Singleton//单例?? fun provideString(): String = "123"}
把Module中的provide方法加上@Singleton注解后就是单例了?,编译一下…
Error:Execution failed for task ‘:app:kaptDebugKotlin’.
Internal compiler error. See log for more details
再看看Gradle Console中的日志:
Component (unscoped) may not reference scoped bindings
原来,对应的Comopnent要加上同样的标记才可以
@Singleton@Component(modules = arrayOf(MainModule::class))interface MainComponent { fun inject(activity: MainActivity)}
再跑一下,编译通过了
再来看看@Singleton
@Scope@Documented@Retention(RUNTIME)public @interface Singleton {}
原来Singleton是一种作用域注解,Component和Module中的provide方法作用域注解相同才能实现单例
什么时候要在构建Component的时候传入Module
之前是这样写的,中间传入了Module
DaggerMainComponent.builder() .mainModule(MainModule()) .build() .inject(this)
把它去掉,照样工作
DaggerMainComponent.builder() .build() .inject(this)
再去看看Dagger生成的代码
public MainComponent build() { if (mainModule == null) { this.mainModule = new MainModule(); } return new DaggerMainComponent(this); }
原来,build方法会自动生成Module,所以可以不传入,拿什么时候才要传入Module呢?修改一下Module,在构造方法中传入参数
@Moduleclass MainModule(val activity: MainActivity) { @Provides @Singleton fun provideString(): String = "123"}
编译之后再来看看生成的方法
public MainComponent build() { if (mainModule == null) { throw new IllegalStateException(MainModule.class.getCanonicalName() + " must be set"); } return new DaggerMainComponent(this); }
卧槽,变了…当Module有参数的时候就需要手动传入了,否则会抛异常。。
- 初探Dagger2遇到的小坑
- 初探Mysql遇到的小问题
- 导入Dagger2遇到的错误
- Dagger2初探(一)
- Dagger2入门初探
- UIScrollView 遇到的小坑
- 使用Dagger2创建的第一个小例子
- 依赖注入框架dagger2的@Scope注解初探(根据生成的源码进行分析)
- 依赖注入框架dagger2的@Scope注解初探(根据生成的源码进行分析)
- 遇到的Hibernate的三个小坑
- 遇到的Hibernate的三个小坑
- PHP学习中遇到的小坑
- Glide图片框架遇到的小坑
- 自定义View遇到的小坑
- AngularJs遇到的小坑与技巧
- Andriod开发中遇到的小坑
- iOS 集成Cordova 遇到的小坑
- ThinkPHP开发中遇到的小坑
- HTML基础--基础标签
- FYN OI奋斗之路9~
- Leetcode [Palindrome Number]
- Flask入门(二)Jinja2 模板
- MyBatis异常java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for
- 初探Dagger2遇到的小坑
- No configuration found for the specified action:问题
- 4种常见的osgi框架比较
- Android小白常识
- 按国家归类的海淘网站大全
- JavaScript 一点都不简单
- 第二次测试中出现的知识不足
- Spring Boot使用Druid和监控配置
- Netty线程模型