Почему он все еще работает без установки AndroidInjectionModule?


Согласно документацииDagger о введении объектов активности , в ней говорится, что установка AndroidInjectionModule в вашем компоненте приложения. Впрочем, все прекрасно и без этого.

Означает ли это, что мне не нужно объявлять об этом? При каких обстоятельствах это будет неправильно?

Например:
Введенный экземпляр

data class Food(val name: String)

Модуль

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

BindingModule

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

Аппкомпонент (без установки AndroidInjectionModule)

@Component(modules = [MainActivityModule::class])
interface AppComponent{
    fun inject(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
    }
}

Основная активность

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}")
    }
}

Он получает шоколад успешно в MainActivity.

1 4

1 ответ:

Означает ли это, что мне не нужно объявлять об этом? При каких обстоятельствах это будет неправильно?

На самом деле кажется, что вам не нужно объявлять его, но это может привести к ошибкам компиляции, если вы этого не сделаете.


Если вы посмотрите на AndroidInjectionModule, вы увидите, что он просто перечисляет кучу методов @Multibinds для типов фреймворков.

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

Теперь, если вы посмотрите вверх Объявление @Multibinds Вы можете прочитать, что

Вы делаете не нужно использовать @Multibinds для наборов или карт, которые имеют хотя бы один @IntoSet, @ElementsIntoSet, или @IntoMap привязка, но вы должны объявить их, если они могут быть пустыми.

И объявлять их, если они могут быть пустыми - это именно то, что модуль AndroidInjectionModule делает для вас. Если части впрыска Android потребуют неопределенной карты заводов инжекторов, вы, вероятно, получите ошибку времени компиляции, заявив, что она не может быть предоставлена.

Причина, по которой вам не нужен модуль, заключается в следующем потому что вы используете @ContributesAndroidInjector, из которого сгенерированный код будет содержать метод @Binds @IntoMap etc., который объявляет карту Привязок. Как указано выше-поскольку он больше не пустой-вам не понадобится дополнительное объявление @Multibinds, которое AndroidInjectionModule обеспечивает непустую многосвязку.


Вы можете ненуждаться в модуле, но он объявит все фабрики инжекторов фреймворка для вас в случае, если они могут быть пустыми, возможно, предотвращая одну или две ошибки компиляции. После того, как весь javadoc просто утверждает, что это должен устанавливаться, а не то, что он должен.

Этот модуль должен быть установлен в компоненте, который используется для внедрения класса приложения.