代码之家  ›  专栏  ›  技术社区  ›  Jono

Dagger 2未注入SharedReference

  •  4
  • Jono  · 技术社区  · 7 年前

    您好,我是dagger 2的新手,正在尝试在我的MyActivity类中插入SharedReference的实例,如下所示:

    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.
    
    1 回复  |  直到 7 年前
        1
  •  12
  •   aleksandrbel    7 年前

    你做得有点不对。首先,现在有了dagger android,它帮助解决了原则问题,解决了组件(如活动)不应该知道注入是如何发生的问题。

    您可以在此处阅读: 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"
    

    您的错误是,您没有告诉您的图形您要向MainActivity中注入。以最好的方式创建 Subcomponent 对于MainActivity,将其与另一个MainActivity模块连接,该模块具有要注入MainActivity的注入,在AppComponent中设置与子组件的连接,并且仅在MainActivity onCreate()方法中注入依赖关系图。但有了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。班 :这是匕首上的。安卓支持库。它为我们的模块提供了Android组件(活动/片段/服务/广播接收器/内容提供者)。

    @组件。建设者 dagger2.10为我们提供了创建DaggerAppComponent生成器的更好方法。

    @绑定状态 在中,生成器将自动创建 MyApplication 所以在 AppModule 我们不需要用MyApplication实例化。它已经是图表中的依赖项。

    ActivityBindingModule。clas公司 是我们的。我以后再谈。

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

    接下来是AppModule。类别:

    @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)
        }
    }
    

    @绑定 注释替换 @Provides 注释,它只返回函数参数中的值。正如您所看到的,图中已经有一个MyApplication实例,无需将MyApplication注入AppModule构造函数。

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

    ActivityBindingModule。类别:

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

    使用 ActivityBindingModule 类,我们只创建单独的模块 子组件 针对我们的Android组件。

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

    主活动模块。类别:

    @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>
    

    对于您的应用程序类,您需要实现DaggerApplication,该应用程序实现HasActivityInjector/HasFragmentInjector/etc以及调用AndroidInjection。inject()。

    关于这一点,您可以在此处阅读更多内容: https://google.github.io/dagger/android.html

    主要活动。类别:

    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 现在不知道SharedReferences是如何注入的。实际上有 AndroidInjection.inject(this); 在DaggerAppCompatActivity中。如果不从此扩展类,则需要自己在onCreate方法中指定它,否则不会进行注入。

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