英文:
How to get Component already initialized with Application context
问题
我刚刚开始使用dagger2,尽管我已经阅读并查阅了文档以获取主要思想,但我不明白注入应用程序上下文的适当方式是什么。
我知道有类似的问题,比如这个或者这个,但这些使用了AndroidInjector,让我更加困惑。我想要理解的是,一旦ContextComponent被初始化并且是一个Singleton,我如何获取ContextComponent的实例(其中包含Application的上下文),以便调用ContextComponent.getSharedPreferenceSpecific()并获得一个使用Application上下文初始化的SharedPreferenceManagerSpecific的实例?
以下是我创建的类,SharedPreferenceManagerSpecific只是为了理解如何向类中注入上下文。
当执行活动的代码时,我得到以下错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.amgdeveloper.articleReader/com.amgdeveloper.articleReader.ui.MainActivity}: java.lang.IllegalStateException: com.amgdeveloper.articleReader.dagger.ContextModule must be set
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
ContextModule.kt
@Module
class ContextModule(private val app: Application) {
@Provides
@Singleton
fun provideContext(): Context = app
}
ContextComponent.kt
@Singleton
@Component(modules = [ContextModule::class])
interface ContextComponent {
fun getSharedPreferenceSpecific(): SharedPreferenceManagerSpecific
fun inject(application: MyApplication)
fun inject(application: MainActivity)
}
MyApplication.kt
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
DaggerContextComponent.builder().contextModule(ContextModule(this)).build()
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val component = DaggerContextComponent.builder().build()
val sharedPreference = component.getSharedPreferenceSpecific()
}
}
SharedPreferenceManagerSpecific.kt
public class SharedPreferenceManagerSpecific() {
lateinit var myContext: Context
@Inject constructor(context: Context) : this() {
myContext = context
}
fun saveIntoSharedPreferences() {
...
}
}
英文:
I just started using dagger2 and in spite of having read and documented myself to get the main ideas, I don't understand which would be the proper way of injecting the application's context.
I know that there are similar questions like this or this but this uses AndroidInjector and I'm getting even more lost. What I would like to understand is once the ContextComponent has been initialised and is a Singleton, how can I retrieve the instance of ContextComponent (that contains the Application's context) in order to call ContextComponent.getSharedPreferenceSpecific() and get an instance of SharedPreferenceManagerSpecific initialised with the Application's context?
The are the classes I have created, SharedPreferenceManagerSpecific it's just to understand how to inject a context to a class.
The error I get when the code of activity is executed i:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.amgdeveloper.articleReader/com.amgdeveloper.articleReader.ui.MainActivity}: java.lang.IllegalStateException: com.amgdeveloper.articleReader.dagger.ContextModule must be set
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
ContextModule.kt
@Module
class ContextModule(private val app: Application) {
@Provides
@Singleton
fun provideContext(): Context = app
}
ContextComponent.tk
@Singleton
@Component(modules = [ContextModule::class])
interface ContextComponent {
fun getSharedPreferenceSpecific ():SharedPreferenceManagerSpecific
fun inject (application: MyApplication)
fun inject (application: MainActivity)
MyApplication.kt
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
DaggerContextComponent.builder().contextModule(ContextModule(this)).build()
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val component = DaggerContextComponent.builder().build()
val sharedPreference = component.getSharedPreferenceSpecific()
}
}
SharedPreferenceManagerSpecific.kt
public class SharedPreferenceManagerSpecific () {
lateinit var myContext : Context
@Inject constructor( context: Context) : this() {
myContext=context
}
fun saveIntoSharedPreferences(){
...
}
}
答案1
得分: 1
Dagger并不在任何地方存储组件实例,甚至不会存储@Singleton
组件实例:在Dagger看来,@Singleton
只是另一种范围而已。为了在你的Application
类中创建一个组件并在Activity
类中使用它,你需要自己将其存储在某个地方。
在大多数使用Dagger的Android应用中,组件存储在Application
中:
class MyApplication : Application() {
// 如果你不使用任何ContentProviders,你可以在onCreate中设置一个lateinit var。
val component by lazy {
DaggerContextComponent.builder().contextModule(ContextModule(this)).build()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val component = (application as MyApplication).component
val sharedPreference = component.getSharedPreferenceSpecific()
}
}
英文:
Dagger doesn't store component instances anywhere. Not even @Singleton
components: as far as Dagger is concerned, @Singleton
is just another scope. In order to create a component in your Application
class and use it in your Activity
class, you will need to store it somewhere yourself.
In most Android apps using Dagger, the component is stored in the Application
:
class MyApplication : Application() {
// You could set a lateinit var in onCreate instead
// if you don't use any ContentProviders.
val component by lazy {
DaggerContextComponent.builder().contextModule(ContextModule(this)).build()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val component = (application as MyApplication).component
val sharedPreference = component.getSharedPreferenceSpecific()
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论