所以,我试图创建一个例子,从GithubBrowserSample和Kotlin一起鼓舞人心。我已成功迁移到kotlin代码但我的ApplicationComponent.kt
收到错误。
Error:(12, 2) error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> cannot be provided without an @Provides-annotated method.
public abstract interface ApplicationComponent {
^
java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> is injected at
dagger.android.DispatchingAndroidInjector.<init>(injectorFactories)
dagger.android.DispatchingAndroidInjector<android.support.v4.app.Fragment> is injected at
com.chintansoni.android.architecturecomponentsblueprint.base.BaseActivity.dispatchingAndroidInjector
com.chintansoni.android.architecturecomponentsblueprint.view.activity.SplashActivity is injected at
dagger.android.AndroidInjector.inject(arg0)
我可以看到问题来自import dagger.android.AndroidInjectionModule
让我分享一下我的代码片段。
KotlinApplication.kt
class KotlinApplication : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun onCreate() {
super.onCreate()
initializeLogger()
initializeAppInjector()
}
private fun initializeAppInjector() {
AppInjector.init(this)
}
private fun initializeLogger() {
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}
override fun activityInjector(): DispatchingAndroidInjector<Activity>? {
return dispatchingAndroidInjector
}
}
AppInjector.kt
object AppInjector {
fun init(kotlinApplication: KotlinApplication) {
DaggerApplicationComponent.builder()
.application(kotlinApplication)
.build()
.inject(kotlinApplication)
kotlinApplication.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)
}
}
ApplicationComponent.kt
@Singleton
@Component(modules = [(AndroidInjectionModule::class), (AppModule::class), (SplashActivityModule::class)])
interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ApplicationComponent
}
fun inject(kotlinApplication: KotlinApplication)
}
SplashActivityModule.kt
@Module
abstract class SplashActivityModule {
@ContributesAndroidInjector(modules = [(FragmentBuildersModule::class)])
internal abstract fun contributeSplashActivity(): SplashActivity
}
BaseActivity.kt
abstract class BaseActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
override fun supportFragmentInjector(): DispatchingAndroidInjector<Fragment> {
return dispatchingAndroidInjector
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutResource())
}
abstract fun getLayoutResource(): Int
}
我的SplashActivity
延长了BaseActivity
。
答案 0 :(得分:1)
如果您使用支持库中的Fragment
,则必须使用HasSupportFragmentInjector
中的KotlinApplication
:
class KotlinApplication : Application(), HasActivityInjector, HasSupportFragmentInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
@Inject
lateinit var dispatchingFragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate() {
super.onCreate()
initializeLogger()
initializeAppInjector()
}
private fun initializeAppInjector() {
AppInjector.init(this)
}
private fun initializeLogger() {
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}
override fun activityInjector(): DispatchingAndroidInjector<Activity>? {
return dispatchingAndroidInjector
}
override fun supportFragmentInjector(): AndroidInjector<Fragment>? {
return dispatchingFragmentInjector
}
}
您还需要在AndroidSupportInjectionModule
中安装AndroidInjectionModule
而不是ApplicationComponent
:
@Singleton
@Component(modules = [(AndroidSupportInjectionModule::class), (AppModule::class), (SplashActivityModule::class)])
interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ApplicationComponent
}
fun inject(kotlinApplication: KotlinApplication)
}
答案 1 :(得分:0)
一切都正确连线。我做错了什么,
在ApplicationComponent
中我添加了AndroidInjectionModule
,这只适用于从Android Framework注入片段。
查看 AndroidInjectionModule 的来源:
package dagger.android;
import android.app.Activity;
import android.app.Fragment;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
import dagger.Module;
import dagger.internal.Beta;
import dagger.multibindings.Multibinds;
import java.util.Map;
/**
* Contains bindings to ensure the usability of {@code dagger.android} framework classes. This
* module should be installed in the component that is used to inject the {@link
* android.app.Application} class.
*/
@Beta
@Module
public abstract class AndroidInjectionModule {
@Multibinds
abstract Map<Class<? extends Activity>, AndroidInjector.Factory<? extends Activity>>
activityInjectorFactories();
@Multibinds
abstract Map<Class<? extends Fragment>, AndroidInjector.Factory<? extends Fragment>>
fragmentInjectorFactories();
@Multibinds
abstract Map<Class<? extends Service>, AndroidInjector.Factory<? extends Service>>
serviceInjectorFactories();
@Multibinds
abstract Map<
Class<? extends BroadcastReceiver>, AndroidInjector.Factory<? extends BroadcastReceiver>>
broadcastReceiverInjectorFactories();
@Multibinds
abstract Map<
Class<? extends ContentProvider>, AndroidInjector.Factory<? extends ContentProvider>>
contentProviderInjectorFactories();
private AndroidInjectionModule() {}
}
没有提及支持库中的碎片。
现在,如果我们查看 AndroidSupportInjectionModule 的来源:
package dagger.android.support;
import android.support.v4.app.Fragment;
import dagger.Module;
import dagger.android.AndroidInjectionModule;
import dagger.android.AndroidInjector;
import dagger.internal.Beta;
import dagger.multibindings.Multibinds;
import java.util.Map;
/**
* Configures bindings to ensure the usability of {@code dagger.android} and {@code
* dagger.android.support} framework classes. This module should be installed in the root-most
* component which will use these types.
*/
@Beta
@Module(includes = AndroidInjectionModule.class)
public abstract class AndroidSupportInjectionModule {
@Multibinds
abstract Map<Class<? extends Fragment>, AndroidInjector.Factory<? extends Fragment>>
supportFragmentInjectorFactories();
private AndroidSupportInjectionModule() {}
}
它包括从支持库中注入Fragment
的支持。
如果您发现,AndroidSupportInjectionModule
还包含AndroidInjectionModule
。因此,仅包括AndroidSupportInjectionModule
将完美地运作。
我的BaseActivity正在实施HasSupportFragmentInjector
,它仅适用于支持片段。 ApplicationComponent中没有包含可以从支持库提供Fragment
依赖关系的模块,这是主要问题。