[英]Is there any way to access contributing modules instances from application component dagger2
I have created a small sample to test dagger2 implementation. 我创建了一个小样本来测试dagger2的实现。 I have created a utility class in which an Activity's instance is to be injected. 我创建了一个实用程序类,其中将插入一个Activity的实例。 Is there any way to get this utility class instance in Activity itself using dagger2 有什么办法可以使用dagger2在Activity本身中获取此实用工具类实例
CoreApplication.kt CoreApplication.kt
class CoreApplication : Application(), HasActivityInjector {
@Inject
internal lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity>
override fun activityInjector(): AndroidInjector<Activity> {
return dispatchingActivityInjector }
val component: AppComponent by lazy {
DaggerAppComponent
.builder()
.application(this)
.sharedPreference(AppConstants.FILE_NAME_SHARED_PREFERENCES)
.build()
}
override fun onCreate() {
super.onCreate()
component.inject(this)
component.sharedPref().saveString("hello", "world")
Log.i("test", component.sharedPref().getString("hello"))
}
}
AppComponent.kt AppComponent.kt
@Singleton
@Component(modules = arrayOf(AndroidInjectionModule::class, ActivityBuilder::class, AppModuleBinds::class, AppModuleProvides::class))
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
@BindsInstance
fun sharedPreference(@Named(Constant.Name.SHARED_PREFERENCES) sharedPreferenceName: String): Builder
fun build(): AppComponent
}
fun inject(application: CoreApplication)
fun sharedPref() : SharedPreferenceUtils
}
ActivityBuilder.kt ActivityBuilder.kt
@Module
abstract class ActivityBuilder{
@PerActivity
@ContributesAndroidInjector(modules = arrayOf(HomeModuleBinds::class))
abstract fun bindMainActivity(): MainActivity
@PerActivity
abstract fun dialogUtils() : DialogUtils
}
HomeModuleBinds.kt HomeModuleBinds.kt
@Module
abstract class HomeModuleBinds {
@Binds
@PerActivity
abstract fun activityContext(activity: Activity): Context
@Binds
@PerActivity
abstract fun activity(activity: Activity): Activity
}
DialogUtils.kt DialogUtils.kt
@PerActivity
class DialogUtils @Inject constructor(var activity: Activity) {
fun showDialog(error: String) = {
val alertDialogBuilder = AlertDialog.Builder(activity)
alertDialogBuilder.setTitle(error).create().show()
}
}
Is there any way I can use DialogUtils instance in MainActivity Using dagger2 dependency cycle? 有什么方法可以在MainActivity中使用drag2依赖周期使用DialogUtils实例吗?
class MainActivity : AppCompatActivity() {
@Inject
@Singleton
lateinit var sharedPref : SharedPreferenceUtils
@Inject
@PerActivity
lateinit var dialogUtils: DialogUtils
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sharedPref.saveString("test", "val")
Log.i("test", sharedPref.getString("test"))
//dialogUtils.showDialog("hello")
}
}
For example using inject for DaggerUtils on MainActivity is causing cyclic dependency error 例如,在MainActivity上对DaggerUtils使用Inject会导致循环依赖性错误
Don't inject the Activity into the Utility class. 不要将Activity注入Utility类。
Then in your Activity call: 然后在您的活动调用中:
dialogUtils.showDialog( "hello", MyACtivity.this)
In dialogUtils: 在dialogUtils中:
fun showDialog(error: String, context: Context) = {
val alertDialogBuilder = AlertDialog.Builder(context)
alertDialogBuilder.setTitle(error).create().show()
}
Is there any way I can use DialogUtils instance in MainActivity Using dagger2 dependency cycle? 有什么方法可以在MainActivity中使用drag2依赖周期使用DialogUtils实例吗?
Yes, there is. 就在这里。 To do that, you'll have to do the following changes in your Dagger setup: 为此,您必须在Dagger设置中进行以下更改:
1. ActivityBuilder.kt 1. ActivityBuilder.kt
Delete the following lines: 删除以下行:
@PerActivity
abstract fun dialogUtils() : DialogUtils
Why? 为什么? You don't need it. 不用了 You already have DialogUtils injectable, since you annotated the class itself with @PerActivity
and the constructor with @Inject
. 您已经拥有DialogUtils可注入的了,因为您使用@PerActivity
注释了类本身,并使用@Inject
注释了构造函数。 Dagger will automagically do the required binding wherever DialogUtils
is needed. Dagger将自动在需要DialogUtils
地方进行所需的绑定。 You write provide/bind methods only when you're injecting an abstract type. 仅在注入抽象类型时才编写provide / bind方法。 In this case, DialogUtils
is not implementing an abstract type that you inject in the Activity
. 在这种情况下, DialogUtils
不会实现您在Activity
注入的抽象类型。 You inject the actual implementation directly so you don't need to setup any bindings. 您直接注入实际的实现,因此不需要设置任何绑定。
2. HomeModuleBinds.kt 2. HomeModuleBinds.kt
Change the Activity binding to more the specific Activity
you want to bind to Activity
, in this case it's MainActivity
. 更改活动结合到更具体的Activity
要结合Activity
,在这种情况下,它的MainActivity
。 Dagger will then understand that it needs to bind it to Activity
when DialogUtils asks for it. 然后,在DialogUtils提出要求时,Dagger将了解需要将其绑定到Activity
。 You will need to do that for each Activity
you want to use DialogUtils in the Activity
's own module - the one you pass as an argument to the @ContributeAndroidInjector(modules = [...])
, in this case it is HomeModuleBinds.kt . 您需要为要在该Activity
自己的模块中使用DialogUtils的每个Activity
执行此操作-您将其作为参数传递给@ContributeAndroidInjector(modules = [...])
,在这种情况下为HomeModuleBinds。 kt 。
@Binds
@PerActivity
abstract fun bindMainActivity(mainActivity: MainActivity): Activity
3. DialogUtils 3. DialogUtils
The way you have method showDialog(String)
defined currently, it returns a lambda! 当前定义方法showDialog(String)
的方式,它返回一个lambda! Remove the equals =
. 删除等于=
。
fun showDialog(error: String) {
val alertDialogBuilder = AlertDialog.Builder(activity)
alertDialogBuilder.setTitle(error).create().show()
}
4. MainActivity.kt 4. MainActivity.kt
Remove the scope annotations from the injected fields. 从注入的字段中删除范围注释。
@Inject
@Singleton // <-- Remove this
lateinit var sharedPref : SharedPreferenceUtils
@Inject
@PerActivity // <-- Remove this
lateinit var dialogUtils: DialogUtils
You can only annotate Components, Provide/Bind methods and classes with scope annotations! 您只能使用范围注释来注释组件,提供/绑定方法和类!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.