从DaggerApplication获取内容解析器时出现空指针异常

时间:2019-09-12 08:47:13

标签: android kotlin dependency-injection dagger-2 dagger

我创建了一个自定义DaggerApplication类,并为其编写了适当的AppModule和AppComponent类,但是在访问injected上下文的内容解析器时出现空指针异常。 (这是我的全局应用程序上下文)。在下面的代码行中,我试图将我的问题缩小为一个小例子。

这是我的应用程序类:

class CustomPlayerApplication @Inject constructor() : DaggerApplication() {
    companion object{
        @SuppressLint("StaticFieldLeak")
        lateinit var context: Context
    }
    override fun onCreate() {
        super.onCreate()
        context = this
    }

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().create(this).build()
    }
}

这是我的AppModule:

@Module
class AppModule {

    @Provides
    @Singleton
    fun providesLibraryManager(application: CustomPlayerApplication): LibraryManager {
        return LibraryManager(application).apply{
               createContentResolver()
        }
    }
}

这是我的应用程序组件:

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        AppModule::class
    ]
)
interface AppComponent : AndroidInjector<CustomPlayerApplication> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun create(app: Application): Builder

        fun build(): AppComponent
    }
    fun libraryManager(): LibraryManager
}

这是我的libraryManager类。

class LibraryManager @Inject constructor(private val context: Context) { 
    fun createContentResolver(): ContentResolver? {
        return context.contentResolver
    }
}

调用contentResolver时,应用程序崩溃并出现空指针异常,表明我无法在空对象上调用contentResolver。在调试时,我发现这里的上下文不是null,但是我也不能调用它的contentResolver。

我确定在将类更改为DaggerApplication并使用2.24之前,我的代码可以正常工作。无论发生什么,都可能是由于@bindInstance注释所致,但是我找不到任何相关问题。

编辑:为进一步解释我的问题,虽然在'AppModule , the app crashes because the context中调用了Provides方法。对null对象引用调用了ContentResolver`,而context不为null且它实际上是我的应用程序上下文。我对真正的问题可能是什么感到困惑。

1 个答案:

答案 0 :(得分:0)

使用AndroidInjector.Factory代替Builder中的AppComponent

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

    @Component.Factory
    interface Factory : AndroidInjector.Factory<CustomPlayerApplication>
}

class CustomPlayerApplication : DaggerApplication() {

    ...

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.factory().create(this)
    }
}

还要注意,您不必使用CustomPlayerApplication来注释@Inject的构造函数。仅当您让Dagger创建类的实例时,该注释才有用。 Dagger不会创建应用程序对象,而是由OS创建的,因此注释是多余的。

同时具有@Provider方法和@Inject的带注释的LibraryManager构造函数似乎也很多余。您可以只使用其中之一。