Android Dagger 2,在模块中提供应用程序上下文
我是Android开发的新手,DI开发的新手。我在一个个人项目中使用Kotlin,我正在试验Dagger 2。我设法将其设置为一个util类,但当我需要一个上下文来使用它注入一个需要上下文的类(sharedpref管理器类)时,我失败了。这是我的代码,这是我得到的错误(NPE)。先谢谢你 我的模块类Android Dagger 2,在模块中提供应用程序上下文,android,kotlin,dagger-2,Android,Kotlin,Dagger 2,我是Android开发的新手,DI开发的新手。我在一个个人项目中使用Kotlin,我正在试验Dagger 2。我设法将其设置为一个util类,但当我需要一个上下文来使用它注入一个需要上下文的类(sharedpref管理器类)时,我失败了。这是我的代码,这是我得到的错误(NPE)。先谢谢你 我的模块类 package com.android.pine import android.content.Context import com.android.pine.utils.SharedPrefer
package com.android.pine
import android.content.Context
import com.android.pine.utils.SharedPreferencesManager
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
@Module
class AppModule {
@Provides
@Singleton
fun context(pineApplication: PineApplication): Context = pineApplication.applicationContext
@Provides
@Singleton
fun provideSharedPrefManager(context: Context): SharedPreferencesManager = SharedPreferencesManager(context)
}
我的组件类:
package com.android.pine
import com.android.pine.home.HomePresenter
import com.android.pine.home.categories.CategoryAdapter
import dagger.Component
import javax.inject.Singleton
@Singleton
@Component(modules = arrayOf(AppModule::class))
interface AppComponent {
fun inject(categoryAdapter: CategoryAdapter)
fun inject(homePresenter: HomePresenter)
}
编辑:添加以下信息,
我如何调用SharedReferencesManager的注入:
class HomePresenter : BasePresenter<HomeView>() {
@Inject
lateinit var sharedPreferencesManager: SharedPreferencesManager
.
.
.
我的pineApplication类和SharedPrefManager类如下所示:
class PineApplication @Inject constructor(): Application()
public class YourApp extends Application {
private static ComponentsManager componentsManager;
@Override
public void onCreate() {
super.onCreate();
initComponentsManager();
initAppComponent();
}
public static ComponentsManager getComponentsManager(){
return componentsManager;
}
private void initComponentsManager(){
componentsManager = new ComponentsManager(this);
}
private void initAppComponent(){
componentsManager.getAppComponent();
}
}
SharedPref:
class SharedPreferencesManager @Inject constructor(context: Context) {
.
.
.
崩溃,无法获取pineApplication.getContext()(已编辑,添加了完整堆栈跟踪)
您不能使用
classpineapplication@injectconstructor():Application()
来创建PineApplication
。它是一个框架类,必须由Android框架创建
执行此操作时,Dagger将创建应用程序
,但应用程序上下文
将返回空值
,因为它从未(由系统)初始化过
不要对框架类使用构造函数注入,也不要自己创建。使用
@Bindsintance
将对象添加到具有其生成器的组件中,或使用模块提供该对象。对于提供应用程序上下文,您可以创建类,如组件管理器
与:
在应用程序类init中,组件管理器如下所示:
class PineApplication @Inject constructor(): Application()
public class YourApp extends Application {
private static ComponentsManager componentsManager;
@Override
public void onCreate() {
super.onCreate();
initComponentsManager();
initAppComponent();
}
public static ComponentsManager getComponentsManager(){
return componentsManager;
}
private void initComponentsManager(){
componentsManager = new ComponentsManager(this);
}
private void initAppComponent(){
componentsManager.getAppComponent();
}
}
您可以尝试这样修改您的应用程序模块
@Module
class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun provideContext(): Context {
return application.applicationContext
}
@Provides
@Singleton
fun provideSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE)
}
}
application.appComponent.inject(this)
然后,您可以从应用程序类中构建这样的dagger组件
val appComponent = DaggerAppComponent.builder()
.applicationModule(ApplicationModule(this))
.build()
像这样在presenter中注入值
@Module
class ApplicationModule(private val application: Application) {
@Provides
@Singleton
fun provideContext(): Context {
return application.applicationContext
}
@Provides
@Singleton
fun provideSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE)
}
}
application.appComponent.inject(this)
就是这样做的。在组件中使用@BindsInstance会将应用程序注入到所有模块中。在您的情况下,只需将应用程序注入到AppModule
@Singleton
@Component(modules = arrayOf(AppModule::class))
interface AppComponent {
@Component.Builder
interface Builder() {
fun build(): AppComponent
@BindsInstance
fun application(application: Application): Builder
}
}
**删除应用程序模块中“提供应用程序”功能的代码,并确保传递应用程序上下文以创建共享引用
@Module
class AppModule {
@Provides
@Singleton
fun provideSharedPrefManager(context: Application): SharedPreferencesManager =
SharedPreferencesManager(context)
}
现在在您的onCreate应用程序类中
DaggerAppComponent.builder().application(this).build()
可选:如果要将某些内容注入到applicationClass中,请执行以下操作
DaggerAppComponent.builder().application(this).build().inject(this)
请包括完整的stacktrace和代码在哪里/如何调用/注入它,这似乎有点奇怪编辑了帖子,添加了更多的信息,为问题的不完整性道歉基于对Android和Dagger的误解,你的代码中有几个错误。这没关系,我们都经历过。我看到的一个问题是您正在注入一个presenter,但是由于您完全控制该类,所以您应该只使用构造函数注入。看看这个博客,它详细地解释了如何使用Dagger建立一个Android项目。你能举个例子吗?在这种情况下如何使用@BindInstance?@tipi你可以或看到这个例子。为什么我在任何帖子上都找不到这个简单有效的例子的答案。我向上帝发誓,如果我没有找到它,我会跳出窗口。如果我理解正确,我会在MainActivity中获取上下文并在那里构建AppComponent。但是我需要注入一些东西,比如一个碎片。我没有这样的背景,那我该怎么做呢?