Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Dagger 2,在模块中提供应用程序上下文_Android_Kotlin_Dagger 2 - Fatal编程技术网

Android Dagger 2,在模块中提供应用程序上下文

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

我是Android开发的新手,DI开发的新手。我在一个个人项目中使用Kotlin,我正在试验Dagger 2。我设法将其设置为一个util类,但当我需要一个上下文来使用它注入一个需要上下文的类(sharedpref管理器类)时,我失败了。这是我的代码,这是我得到的错误(NPE)。先谢谢你

我的模块类

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。但是我需要注入一些东西,比如一个碎片。我没有这样的背景,那我该怎么做呢?