gpt4 book ai didi

android - Dagger 2 没有注入(inject) sharedPreference

转载 作者:太空狗 更新时间:2023-10-29 16:11:12 32 4
gpt4 key购买 nike

您好,我是 dagger 2 的新手,正在尝试在下面的 MyActivity 类中注入(inject)一个 sharedPreference 实例:

class MyApplication : Application() {

companion object {
@JvmStatic lateinit var applicationComponent : ApplicationComponent
}



override fun onCreate() {
super.onCreate()
applicationComponent = DaggerApplicationComponent.builder().androidModule(AndroidModule(this)).build()

}
}

这里是组件和模块

@Singleton
@Component(modules = arrayOf(AndroidModule::class))
interface ApplicationComponent {
fun inject(mainActivity: MainActivity)
}

@Module
class AndroidModule (private val application: Application){

@Provides
@Singleton
fun provideApplicationContext() : Context = application

@Provides
@Singleton
fun provideSharedPreference() : SharedPreferences = application.getSharedPreferences("shared pref", Context.MODE_PRIVATE)

}


class MainActivity: Activity{
@Inject
internal lateinit var sharedPreference: SharedPreferences

@Inject
internal lateinit var MainScreenPresenter: MainScreenContract.Presenter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_Screen)
MyApplication.applicationComponent.inject(this)

sharedPreference.toString()

initiateViews()
}

}

我收到以下错误:

Error:(7, 1) error: android.content.SharedPreferences cannot be provided without an @Provides- or @Produces-annotated method.

最佳答案

你做的有点不对。首先,现在有 dagger-android 帮助解决了组件(例如 Activity)不应该知道注入(inject)是如何发生的问题的原理问题。

您可以在这里阅读:https://medium.com/@iammert/new-android-injector-with-dagger-2-part-1-8baa60152abe

只是为了确保 dagger 依赖项在 Android 项目中:

android {
kapt {
generateStubs = true
}
}

compile "com.google.dagger:dagger:2.13"
compile "com.google.dagger:dagger-android:2.13"
compile "com.google.dagger:dagger-android-support:2.13"
kapt "com.google.dagger:dagger-compiler:2.13"
kapt "com.google.dagger:dagger-android-processor:2.13"

你的错误是你没有告诉你的图表你想要注入(inject) MainActivity。最好的方法是为 MainActivity 创建 Subcomponent,将其与 MainActivity 的另一个模块连接,该模块具有要注入(inject) MainActivity 的注入(inject),在 AppComponent 中设置与 Subcomponent 的连接,并且仅在 MainAcitivy 中设置onCreate() 方法注入(inject)您的依赖关系图。但是有了 dagger-android,一切都变得更容易了。

代码如下:

@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
ActivityBindingModule::class,
AppModule::class
])
interface AppComponent : AndroidInjector<DaggerApplication> {

fun inject(application: MyApplication)

override fun inject(instance: DaggerApplication)

@Component.Builder
interface Builder {
@BindsInstance fun application(application: MyApplication): Builder
fun build(): AppComponent
}
}

AndroidSupportInjectionModule.class:这来自 dagger.android.support 库。它为我们的模块提供了 Android 组件(Activities/Fragments/Services/BroadcastReceiver/ContentProvider)。

@Component.Builder 在 dagger2.10 中为我们提供了更好的方法来创建 DaggerAppComponent 的构建器。

Builder 中的

@BindsInstance 会自动创建一个MyApplication 的实例,所以在AppModule 中我们不需要用MyApplication 实例化。它已经是图中的依赖项。

ActivityBindingModule.clas 是我们的。以后再说。

您可以在此处阅读有关此部分的更多信息:https://proandroiddev.com/dagger-2-component-builder-1f2b91237856

接下来是 AppModule.class :

@Module
abstract class AppModule{

@Binds
abstract fun provideContext(application: MyApplication) : Context

@Module
companion object {

@JvmStatic
@Provides
fun provideSharedPreferences(context: Context): SharedPreferences =
context.getSharedPreferences("SharedPreferences", Context.MODE_PRIVATE)
}
}

@Binds 注释替换了 @Provides 注释,它只返回函数参数中的值。如您所见,图中已经有一个 MyApplication 实例,无需在 AppModule 构造函数中注入(inject) MyApplication。

注意:带有@Binds 注解的函数应该是抽象的,如果有带有@Provides 注解的函数,它们应该是static。您可以在此处找到 Kotlin 中静态函数的解决方案:https://github.com/google/dagger/issues/900

ActivityBindingModule.class:

@Module
abstract class ActivityBindingModule {

@ContributesAndroidInjector(modules = [MainActivityModule::class])
internal abstract fun bindMainActivity(): MainActivity
}

使用 ActivityBindingModule 类,我们只需创建单独的模块,该模块将为我们创建 Android 组件的子组件

有关 ContributesAndroidInjector 和 Bind 的更多信息,您可以在此处阅读: https://proandroiddev.com/dagger-2-annotations-binds-contributesandroidinjector-a09e6a57758f

MainActivityModule.class:

@Module
abstract class MainActivityModule {

@Binds
internal abstract fun provideMainActivity(activity: MainActivity): MainActivity
}

我的应用程序类:

class MyApplication: DaggerApplication(){

override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
val appComponent = DaggerAppComponent.builder()
.application(this)
.build()
appComponent.inject(this)
return appComponent
}
}

不要忘记在 Mainfest 文件中插入应用程序。

<application
android:name=".MyApplication"
...
>
...
</application>

对于您的 Application 类,您需要实现 DaggerApplication,它实现了 HasActivityInjector/HasFragmentInjector/etc 以及调用 AndroidInjection.inject()。

关于这个你可以在这里阅读更多:https://google.github.io/dagger/android.html

MainActivity.class:

class MainActivity : DaggerAppCompatActivity() {

@Inject
lateinit var sharedPreferences: SharedPreferences

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TAAAAG", sharedPreferences.toString())
}
}

如您所见,MainActivity 现在不知道 SharedPreferences 是如何注入(inject)的。实际上在 DaggerAppCompatActivity 中有 AndroidInjection.inject(this);。如果你不从这个扩展你的类,那么你需要自己在 onCreate 方法中指定它,否则将不会进行注入(inject)。

编辑:您可以从 GitHub 查看代码:https://github.com/Belka1000867/Dagger2Kotlin

关于android - Dagger 2 没有注入(inject) sharedPreference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48081881/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com