【发布时间】:2020-09-24 16:15:49
【问题描述】:
我一直致力于将我们的 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
好的http 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.
到目前为止,作为这次迁移的一部分,我已经将几个类从单例迁移到了它们自己的范围,如 Singleton component cannot depend on scoped components 中所讨论的那样
我也尝试关注这里的信息:http://frogermcs.github.io/activities-multibinding-in-dagger-2/ 以及其他一些信息,但我还无法让构建与 AS4 一起编译。本项目在升级前是3.0.1编译的。
现在进入代码: 应用.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:
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:
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<*, *>
}
提前感谢您的帮助!
【问题讨论】:
-
你找到解决方案了吗?
标签: android android-studio kotlin dagger-2