Невозможно использовать пользовательскую область в компоненте кинжала - PullRequest
0 голосов
/ 01 мая 2020

Я модулирую одно из моих Android приложений. В котором я использую Dagger для инъекции зависимости. Это работало нормально с одним модулем.

Но с тех пор, как я создал 3 модуля, я столкнулся со многими проблемами, в основном из-за Кинжала. Модули в приложении: приложение , ядро ​​, функция . Я пытаюсь сохранить весь общий код в базовом модуле. Поэтому я интегрировал Dagger в свой основной модуль, используя article . Когда я пытаюсь использовать пользовательский Scope (ie AppScope) для моего AppComponent, чтобы связать его с основным модулем. Я получаю ниже ошибки. Однако Singleton работает.

E:\shahbaz\ultimate-downloader\app\build\tmp\kapt3\stubs\debug\matrixsystems\ultimatedownloader\di\components\AppComponent.java:12: error: [Dagger/IncompatiblyScopedBindings] matrixsystems.ultimatedownloader.di.components.AppComponent scoped with @matrixsystems.ultimatedownloader.di.AppScope may not reference bindings with different scopes:
public abstract interface AppComponent {

Код, который я использую:

AppComponent.kt

@AppScope // Singleton is working
@Component(modules = [AndroidInjectionModule::class, AppModule::class])
interface AppComponent {

@Component.Builder
interface Builder {

    @BindsInstance
    fun application(app: AppController): Builder

    fun build(): AppComponent
}

fun inject(app: AppController)

}

AppModule.kt

@Module(includes = [ActivityModule::class, ViewModelModule::class])
class AppModule {

/**
 * Application application level context.
 */
@Singleton
@Provides
fun provideContext(application: AppController): Context {
    return application.applicationContext
}


/**
 * Application resource provider, so that we can get the Drawable, Color, String etc at runtime
 */
@Provides
@Singleton
fun providesResources(application: AppController): Resources = application.resources

}

ActivityModule .kt

@Module(includes = [FragmentModule::class]) // Including Fragment Module Available For Activities
internal abstract class ActivityModule {

/**
 * Marking Activities to be available to contributes for Android Injector
 */
@ContributesAndroidInjector
abstract fun contributeMainActivity(): MainActivity

}

FragmentModule.kt

@Module
internal abstract class FragmentModule {

@ContributesAndroidInjector
internal abstract fun contributeDownloadsFragment(): DownloadsFragment
}

ViewModelModule.kt

@Module
internal abstract class ViewModelModule {

@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
abstract fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(DownloadsViewModel::class)
abstract fun bindDownloadsViewModel(downloadsViewModel: DownloadsViewModel): ViewModel

/**
 * Binds ViewModels factory to provide ViewModels.
 */
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory

}

AppController.kt

class AppController : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

override fun onCreate() {
    super.onCreate()
    AppInjector.initApp(this)
}

override fun activityInjector(): AndroidInjector<Activity> {
    return dispatchingAndroidInjector
}
}

AppInjector.kt

object AppInjector {

fun initApp(app: AppController) {
    DaggerAppComponent.builder().application(app).build().inject(app)

    app.registerActivityLifecycleCallbacks(object :
        Application.ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            handleActivity(activity)
        }

        override fun onActivityStarted(activity: Activity) {}

        override fun onActivityResumed(activity: Activity) {}

        override fun onActivityPaused(activity: Activity) {}

        override fun onActivityStopped(activity: Activity) {}

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}

        override fun onActivityDestroyed(activity: Activity) {}
    })
}

private fun handleActivity(activity: Activity) {
    if (activity is HasSupportFragmentInjector) {
        AndroidInjection.inject(activity)
    }
    (activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
        object : FragmentManager.FragmentLifecycleCallbacks() {
            override fun onFragmentCreated(
                fm: FragmentManager,
                f: Fragment,
                savedInstanceState: Bundle?
            ) {
                if (f is Injectable) {
                    AndroidSupportInjection.inject(f)
                }
            }
        }, true
    )
}
}

Я провел 2 дня, но все равно не повезло. Я просто хочу добавить функциональный модуль ядра с Dagger. Мы высоко ценим любую рабочую статью или пример кода, которые я могу использовать без внесения значительных изменений в существующий модуль приложения.

...