Why it still works without installing AndroidInjectionModule?

女生的网名这么多〃 提交于 2019-12-06 06:11:31

问题


According to Dagger documentation about injecting activity objects, it says that installing AndroidInjectionModule in your application component. However, everything is fine without it.

Does it means that I don't need to declare it? Under what circumstances will it be wrong?

For example:
Injected instance

data class Food(val name: String)

Module

@Module
class FoodModule{
    @Provides
    fun provideFood(): Food {
        return Food("cholocate")
    }
}

BindingModule

@Module
abstract class MainActivityModule {
    @ContributesAndroidInjector(modules = [FoodModule::class])
    abstract fun FoodShop(): MainActivity
}

AppComponent (Without installing AndroidInjectionModule)

@Component(modules = [MainActivityModule::class])
interface AppComponent{
    fun inject(app: App)
}

App

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

    override fun onCreate() {
        super.onCreate()
        DaggerAppComponent.create().inject(this)
    }

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

MainActivity

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var food: Food

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d("test", "Get ${food.name}")
    }
}

It get chocolate successfully in MainActivity.


回答1:


Does it means that I don't need to declare it? Under what circumstances will it be wrong?

It actually seems like you don't need to declare it, but it might lead to compile errors if you don't.


If you have a look at AndroidInjectionModule you can see that it just lists a bunch of @Multibinds methods for framework types.

@Multibinds
abstract Map<Class<? extends Activity>, AndroidInjector.Factory<? extends Activity>>
    activityInjectorFactories();

Now if you look up Declaring @Multibinds you can read that

You do not have to use @Multibinds for sets or maps that have at least one @IntoSet, @ElementsIntoSet, or @IntoMap binding, but you do have to declare them if they may be empty.

And to declare them if they may be empty is exactly what the AndroidInjectionModule module is doing for you. If the Android Injection parts would require an undefined Map of injector factories you would probably get a compile time error stating that it cannot be provided.

The reason that you don't need the module is because you're using @ContributesAndroidInjector, of which the generated code will contain a @Binds @IntoMap etc. method, that declares the bindings map. Stated above—as it is not empty anymore—you would not need the additional @Multibinds declaration that AndroidInjectionModule provides for the non-empty multibinding.


You might not need the module, but it will declare all the framework injector factories for you in case that they might be empty, possibly preventing one or two compile errors. After all the javadoc simply states that it should be installed, not that it must.

This module should be installed in the component that is used to inject the Application class.



来源:https://stackoverflow.com/questions/48134255/why-it-still-works-without-installing-androidinjectionmodule

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!