簡體   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

我一直致力於將我們的 Android 項目從 Android Studio 3.0.1 升級到 4.0.1,作為其中的一部分,我升級了以下內容:

構建工具版本 26.0.2 -> 30.0.2

編譯 SDK 版本 25 -> 28

Kotlin 版本 1.2.71 -> 1.4.10

Gradle 版本 3.1.0 -> 4.0.1

Android 支持 v7 -> androidx 1.0.0

匕首 2.9 -> 2.28.3

改造 2.2.0 -> 2.9.0

Okhttp 3.7.0 -> 4.9.0

我現在遇到了一個問題,出現以下錯誤:

@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.

到目前為止,作為遷移的一部分,我已經將幾個類從單例轉移到了它們自己的作用域中,如單例組件不能依賴作用域組件中所述

我也嘗試遵循這里的信息:http ://frogermcs.github.io/activities-multibinding-in-dagger-2/以及其他一些東西,但我還沒有能夠得到構建用AS4編譯。 本項目在升級前在3.0.1編譯。


現在進入代碼: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]
    }
}

應用組件.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)
}

應用模塊.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)
    }
}

活動綁定模塊:

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<*, *>

}

提前感謝你的幫助!

它說 FragmentComponentBuilder 缺少代碼 - 我沒有看到您在帖子中創建 FragmentComponentBuilder 的位置,所以也許可以開始查看那里並檢查您的所有片段是否已正確注入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM