热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

匕首2不注入sharedPreference

如何解决《匕首2不注入sharedPreference》经验,为你挑选了1个好方法。

嗨,我是匕首2的新手,并尝试在下面的MyActivity类中注入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.

aleksandrbel.. 7

您做的有点不正确。首先,现在有了Dagger-android,它可以解决一些原理性问题,该问题解决了组件(例如Activity)不应该知道注入如何发生的问题。

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

只是为了确保匕首依赖项在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中设置与Subcomponent的连接,并且仅在MainAcitivy onCreate()方法中注入依赖关系图。但是使用Dagger-android,一切都变得更加容易。

这是代码:

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

    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组件(活动/片段/服务/ BroadcastReceiver / ContentProvider)。

dagger2.10中的@ Component.Builder为我们提供了更好的创建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构造函数中注入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类,我们只创建了一个单独的Module,它将为我们为Android组件创建组件。

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

MainActivityModule.class:

@Module
abstract class MainActivityModule {

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

MyApplication.class:

class MyApplication: DaggerApplication(){

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

不要忘记在Mainfest文件中插入Application。


    ...

对于您的Application类,您需要实现实现HasActivityInjector / HasFragmentInjector / etc的DaggerApplication,并调用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。实际上AndroidInjection.inject(this);在DaggerAppCompatActivity中。如果您不从中扩展您的类,那么您需要自己在onCreate方法中指定它,否则将不会进行注入。

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



1> aleksandrbel..:

您做的有点不正确。首先,现在有了Dagger-android,它可以解决一些原理性问题,该问题解决了组件(例如Activity)不应该知道注入如何发生的问题。

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

只是为了确保匕首依赖项在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中设置与Subcomponent的连接,并且仅在MainAcitivy onCreate()方法中注入依赖关系图。但是使用Dagger-android,一切都变得更加容易。

这是代码:

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

    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组件(活动/片段/服务/ BroadcastReceiver / ContentProvider)。

dagger2.10中的@ Component.Builder为我们提供了更好的创建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构造函数中注入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类,我们只创建了一个单独的Module,它将为我们为Android组件创建组件。

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

MainActivityModule.class:

@Module
abstract class MainActivityModule {

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

MyApplication.class:

class MyApplication: DaggerApplication(){

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

不要忘记在Mainfest文件中插入Application。


    ...

对于您的Application类,您需要实现实现HasActivityInjector / HasFragmentInjector / etc的DaggerApplication,并调用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。实际上AndroidInjection.inject(this);在DaggerAppCompatActivity中。如果您不从中扩展您的类,那么您需要自己在onCreate方法中指定它,否则将不会进行注入。

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


推荐阅读
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了一种求解最小权匹配问题的方法,使用了拆点和KM算法。通过将机器拆成多个点,表示加工的顺序,然后使用KM算法求解最小权匹配,得到最优解。文章给出了具体的代码实现,并提供了一篇题解作为参考。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
author-avatar
猫猫爱妞_462
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有