简体   繁体   English

从 Android Studio 3.0.1 升级到 4.0.1 和 Dagger 2.9 -> 2.25.3 后的 Dagger 问题

[英]Dagger issues after upgrading from Android Studio 3.0.1 to 4.0.1 and Dagger 2.9 -> 2.25.3

I've been working on upgrading our Android project from Android Studio 3.0.1 to 4.0.1, and as part of that, I have upgraded the following:我一直致力于将我们的 Android 项目从 Android Studio 3.0.1 升级到 4.0.1,作为其中的一部分,我升级了以下内容:

Build Tools Version 26.0.2 -> 30.0.2构建工具版本 26.0.2 -> 30.0.2

Compile SDK Version 25 -> 28编译 SDK 版本 25 -> 28

Kotlin version 1.2.71 -> 1.4.10 Kotlin 版本 1.2.71 -> 1.4.10

Gradle version 3.1.0 -> 4.0.1 Gradle 版本 3.1.0 -> 4.0.1

Android Support v7 -> androidx 1.0.0 Android 支持 v7 -> androidx 1.0.0

Dagger 2.9 -> 2.28.3匕首 2.9 -> 2.28.3

Retrofit 2.2.0 -> 2.9.0改造 2.2.0 -> 2.9.0

Okhttp 3.7.0 -> 4.9.0 Okhttp 3.7.0 -> 4.9.0

I am now running into an issue where I am getting an error saying the following:我现在遇到了一个问题,出现以下错误:

@dagger.Component(dependencies = {org.bbb.ccc.app.application.AppComponent.class}, modules = {org.bbb.ccc.app.ddd.yyy.zzz.class})
^
      @Singleton org.bbb.ccc.app.application.AppComponent/Users/xxx/aaa_android/app/build/tmp/kapt3/stubs/eee/org/xxx/ddd/app/application/AppComponent.java:8: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends error.NonExistentClass>,javax.inject.Provider<org.bbb.ccc.app.dagger.fragment.FragmentComponentBuilder<?,?>>> cannot be provided without an @Provides-annotated method.

So far, as part of this migration, I have moved several classes from being a Singleton to their own scope, as discussed in Singleton component cannot depend on scoped components到目前为止,作为迁移的一部分,我已经将几个类从单例转移到了它们自己的作用域中,如单例组件不能依赖作用域组件中所述

I have also tried to follow the information here:http://frogermcs.github.io/activities-multibinding-in-dagger-2/ as well as a few other things, and I have not yet been able to get the build to compile with AS4.我也尝试遵循这里的信息:http ://frogermcs.github.io/activities-multibinding-in-dagger-2/以及其他一些东西,但我还没有能够得到构建用AS4编译。 This project compiled in 3.0.1 before upgrading.本项目在升级前在3.0.1编译。


Onto code now: App.kt:现在进入代码:App.kt:


package org.bbb.ccc.app.application

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.os.StrictMode
import android.util.Log
import com.crashlytics.android.Crashlytics
import io.fabric.sdk.android.Fabric
import io.realm.Realm
import io.realm.RealmConfiguration
import org.bbb.ccc.app.dagger.activity.ActivityComponentBuilder
import org.bbb.ccc.app.dagger.activity.HasActivitySubcomponentBuilders
import org.bbb.ccc.app.data.migration.KäsefüßeRealmMigration
import org.bbb.ccc.app.data.repository.RealmDatabase
import org.bbb.ccc.app.utils.logouttimer.LogoutTimerService
import javax.inject.Inject


/**
 * Application Class (Debug Version)
 * @desc - Instantiate a Base class for all Android Activities and Services.  Also creates global
 * objects for Realm, Dagger, Analytics, Memory Management, etc.
 */
open class App : Application(), HasActivitySubcomponentBuilders {
    companion object {
        var context: Context? = null
    }

    @Inject
    lateinit var activityComponentBuilders: MutableMap<Class<out Activity?>?, @JvmSuppressWildcards ActivityComponentBuilder<*, *>?>

    lateinit var appComponent: AppComponent

    override fun onCreate() {
        super.onCreate()
        context = this

        // Set Crashlytics for Firebase
        Fabric.with(this, Crashlytics())

        createRealm("KäsefüßeDebug.Realm", 4L)

        appComponent = createAppComponent()
        appComponent.inject(this)
        try{
            Intent(this, LogoutTimerService::class.java).also { intent ->
                startService(intent)
            }
        } catch (e: IllegalStateException){
            Log.d("Käsefüße", e.toString())
        }


        StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .build())

        StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .build())
    }

    override fun onTerminate() {
        LogoutTimerService.sharedInstance.cancelTimer()
        Intent(this, LogoutTimerService::class.java).also { intent ->
            stopService(intent)
        }

        super.onTerminate()
    }

    protected open fun createAppComponent() : AppComponent {
        return DaggerAppComponent.builder()
                .appModule(AppModule(this))
                .apiModule(ApiModule())
                .dbModule(DbModule())
                .build()
    }

    protected open fun createRealm(realmName: String, realmVersion: Long) {
        Realm.init(this)

        RealmDatabase.realmConfiguration = RealmConfiguration.Builder()
                .name(realmName)
                .schemaVersion(realmVersion)
                .migration(KäsefüßeRealmMigration())
                .build()
    }

    override fun getBuilder(activityClass: Class<out Activity?>?): ActivityComponentBuilder<*, *>? {
        return activityComponentBuilders[activityClass]
    }
}

AppComponent.kt:应用组件.kt:

package org.bbb.ccc.app.application

import android.content.Context
import dagger.Component
import org.bbb.ccc.app.vol.ComplimenteuseService
import org.bbb.ccc.app.dagger.activity.ActivityBindingModule
import org.bbb.ccc.app.data.preference.PreferenceFactory
import org.bbb.ccc.app.Fromage.FromageService
import org.bbb.ccc.app.nourriture.Ananas.AnanasActivity
import org.bbb.ccc.app.nourriture.pommeDuTerre.PommeDuTerreActivity
import javax.inject.Singleton

@Singleton
@Component(modules = [AppModule::class, ActivityBindingModule::class])
interface AppComponent {

    fun inject(app: App)

    fun inject(FromageService: FromageService)

    fun inject(complimenteuseService: ComplimenteuseService)

    fun context() : Context

    fun preferenceFactory() : PreferenceFactory

    fun inject(ananasActivity: AnanasActivity)

    fun inject(pommeDuTerreActivity: PommeDuTerreActivity)
}

AppModule.kt:应用模块.kt:

package org.bbb.ccc.app.application

import android.content.Context
import android.content.SharedPreferences
import com.google.gson.Gson
import dagger.Module
import dagger.Provides
import io.reactivex.Scheduler
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.bbb.ccc.app.bluetooth.BTUtils
import org.bbb.ccc.app.data.preference.PreferenceFactory
import org.bbb.ccc.app.domain.model.Profile
import org.bbb.ccc.app.domain.network.KäsefüßeAPI
import org.bbb.ccc.app.domain.repository.ComplimenteuseRepository
import org.bbb.ccc.app.domain.repository.TrainRepository
import org.bbb.ccc.app.domain.repository.UserRepository
import org.bbb.ccc.app.login.interactor.ProfileInteractor
import org.bbb.ccc.app.login.interactor.ProfileManager
import org.bbb.ccc.app.presentation.interactor.SchedulerProvider
import org.bbb.ccc.app.utils.android.DeviceNameGenerator
import org.bbb.ccc.app.utils.android.HasConnection
import org.bbb.ccc.app.utils.connectionstate.ConnectionBroadCastReceiverRegistry
import org.bbb.ccc.app.utils.connectionstate.ConnectionNotifier
import org.bbb.ccc.app.utils.connectionstate.OkHttpPingService
import org.bbb.ccc.app.utils.extensions.hasInternetConnection
import javax.inject.Singleton

/**
 * App Module - Dagger.
 */
@Module(includes = [ApiModule::class, DbModule::class])
class AppModule(private val application: App) {

    @Provides
    @Singleton
    fun app(): App = application

    @Provides
    @Singleton
    fun sharedPreferences(): SharedPreferences =
            application.getSharedPreferences("PREFS", Context.MODE_PRIVATE)

    @Provides
    @Singleton
    fun applicationContext() : Context = application

    @Provides
    @Singleton
    fun schedulerProvider() : SchedulerProvider {
        return object : SchedulerProvider {
            override fun ui(): Scheduler = AndroidSchedulers.mainThread()

            override fun computation(): Scheduler = Schedulers.computation()

            override fun trampoline(): Scheduler = Schedulers.trampoline()

            override fun newThread(): Scheduler = Schedulers.newThread()

            override fun io(): Scheduler = Schedulers.io()
        }
    }

    @Provides
    @Singleton
    fun preferencesManager(sharedPreferences: SharedPreferences, gson: Gson) : PreferenceFactory =
            PreferenceFactory(sharedPreferences, gson)

    @Provides
    @Singleton
    fun profileInteractor(preferenceFactory: PreferenceFactory, trainRepository: TrainRepository,
                          userRepository: UserRepository, schedulerProvider: SchedulerProvider)
            : ProfileManager {
        val preference = preferenceFactory.create<Profile>(PreferenceFactory.PreferenceKey.PROFILE)
        return ProfileInteractor(preference, trainRepository, userRepository, schedulerProvider)
    }

    @Provides
    @Singleton
    fun hasConnection() : HasConnection {
        return object : HasConnection {
            override fun available(): Boolean = application.hasInternetConnection()
        }
    }

    @Provides
    @Singleton
    fun connectionNotifier(context: Context, hasConnection: HasConnection, schedulerProvider: SchedulerProvider)
            : ConnectionNotifier =
            ConnectionNotifier(OkHttpPingService(), ConnectionBroadCastReceiverRegistry(context), hasConnection, schedulerProvider)

    @Provides
    @Singleton
    fun ComplimenteuseInteractor(ComplimenteuseRepository: ComplimenteuseRepository,
                           KäsefüßeAPI: KäsefüßeAPI,
                           hasConnection: HasConnection,
                           preferenceFactory: PreferenceFactory,
                           schedulerProvider: SchedulerProvider): ComplimenteuseManager {
        val preference = preferenceFactory.create<Profile>(PreferenceFactory.PreferenceKey.PROFILE)
        val deviceNameGenerator = object : DeviceNameGenerator {
            override fun name(): String = BTUtils.deviceName
        }
        return ComplimenteuseInteractor(ComplimenteuseRepository, KäsefüßeAPI, hasConnection, preference, deviceNameGenerator, schedulerProvider)
    }
}

ActivityBindingModule:活动绑定模块:

package org.bbb.ccc.app.dagger.activity

import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
import org.bbb.ccc.app.vol.AeroplanActivity
import org.bbb.ccc.app.vol.AeroplanComponent
import org.bbb.ccc.app.login.LoginActivity
import org.bbb.ccc.app.login.LoginComponent
import org.bbb.ccc.app.nourriture.viande.BoeufActivity
import org.bbb.ccc.app.nourriture.viande.BoeufComponent
import org.bbb.ccc.app.nourriture.fruit.PommeComponent
import org.bbb.ccc.app.nourriture.fruit.CarambolaActivity
import org.bbb.ccc.app.nourriture.fruit.RaisinActivity
import org.bbb.ccc.app.nourriture.fruit.RaisinComponent
import org.bbb.ccc.app.KäsefüßeKäse.KäseActivity
import org.bbb.ccc.app.KäsefüßeKäse.KäseComponent

/**
 * Created by Bob Jones on 4/26/17.
 */
@Module(
        subcomponents = [LoginComponent::class, AeroplanComponent::class, KäseComponent::class, PommeComponent::class, BoeufComponent::class, RaisinComponent::class]
)
abstract class ActivityBindingModule {

    @Binds
    @IntoMap
    @ActivityKey(LoginActivity::class)
    abstract fun loginComponentBuilder(impl: LoginComponent.Builder) : ActivityComponentBuilder<*, *>

    @Binds
    @IntoMap
    @ActivityKey(AeroplanActivity::class)
    abstract fun AeroplanComponentBuilder(impl: AeroplanComponent.Builder) : ActivityComponentBuilder<*, *>

    @Binds
    @IntoMap
    @ActivityKey(KäseActivity::class)
    abstract fun KäseActivityComponentBuilder(impl: KäseComponent.Builder) : ActivityComponentBuilder<*, *>

    @Binds
    @IntoMap
    @ActivityKey(CarambolaActivity::class)
    abstract fun carambolaComponentBuilder(impl: PommeComponent.Builder) : ActivityComponentBuilder<*, *>

    @Binds
    @IntoMap
    @ActivityKey(BoeufActivity::class)
    abstract fun boeufActivity(impl: BoeufComponent.Builder) : ActivityComponentBuilder<*, *>

    @Binds
    @IntoMap
    @ActivityKey(RaisinActivity::class)
    abstract fun RaisinComponentBuilder(impl: RaisinComponent.Builder) : ActivityComponentBuilder<*, *>

}

Thanks in advance for your assistance!提前感谢你的帮助!

它说 FragmentComponentBuilder 缺少代码 - 我没有看到您在帖子中创建 FragmentComponentBuilder 的位置,所以也许可以开始查看那里并检查您的所有片段是否已正确注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM