我创建了一个小样本来测试dagger2的实现。我创建了一个实用程序类,其中将注入Activity的实例。有没有办法使用dagger2
在Activity本身中获取此实用程序类实例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
@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
@Module
abstract class ActivityBuilder{
@PerActivity
@ContributesAndroidInjector(modules = arrayOf(HomeModuleBinds::class))
abstract fun bindMainActivity(): MainActivity
@PerActivity
abstract fun dialogUtils() : DialogUtils
}
HomeModuleBinds.kt
@Module
abstract class HomeModuleBinds {
@Binds
@PerActivity
abstract fun activityContext(activity: Activity): Context
@Binds
@PerActivity
abstract fun activity(activity: Activity): Activity
}
DialogUtils.kt
@PerActivity
class DialogUtils @Inject constructor(var activity: Activity) {
fun showDialog(error: String) = {
val alertDialogBuilder = AlertDialog.Builder(activity)
alertDialogBuilder.setTitle(error).create().show()
}
}
有没有办法在MainActivity中使用DialogUtils实例使用dagger2依赖循环?
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")
}
}
例如,在MainActivity上使用inject for DaggerUtils会导致循环依赖性错误
答案 0 :(得分:0)
不要将Activity注入Utility类。
然后在你的活动电话中:
dialogUtils.showDialog( "hello", MyACtivity.this)
在dialogUtils中:
fun showDialog(error: String, context: Context) = {
val alertDialogBuilder = AlertDialog.Builder(context)
alertDialogBuilder.setTitle(error).create().show()
}
答案 1 :(得分:0)
有什么方法可以使用dagger2依赖周期在MainActivity中使用DialogUtils实例吗?
是的,有。为此,您必须在Dagger设置中进行以下更改:
1。 ActivityBuilder.kt
删除以下几行:
@PerActivity
abstract fun dialogUtils() : DialogUtils
为什么?不用了您已经可以注入 DialogUtils ,因为您已经用@PerActivity
注释了类本身,并用@Inject
注释了构造函数。 Dagger会在需要DialogUtils
的地方自动进行所需的绑定。仅在注入抽象类型时才编写provide / bind方法。在这种情况下,DialogUtils
没有实现您在Activity
中注入的抽象类型。您可以直接注入实际的实现,因此无需设置任何绑定。
2。 HomeModuleBinds.kt
将“活动”绑定更改为更多您想要绑定到Activity
的特定Activity
,在本例中为MainActivity
。然后,Dagger会在 DialogUtils 要求时将其绑定到Activity
。您需要为要在Activity
自己的模块中使用 DialogUtils 的每个Activity
进行此操作-您将其作为参数传递给{{1} },在这种情况下为 HomeModuleBinds.kt 。
@ContributeAndroidInjector(modules = [...])
3。 DialogUtils
您当前定义方法@Binds
@PerActivity
abstract fun bindMainActivity(mainActivity: MainActivity): Activity
的方式将返回一个lambda!删除等于showDialog(String)
。
=
4。 MainActivity.kt
从注入的字段中删除范围注释。
fun showDialog(error: String) {
val alertDialogBuilder = AlertDialog.Builder(activity)
alertDialogBuilder.setTitle(error).create().show()
}
您只能使用范围注释来注释组件,提供/绑定方法和类!