Skip to content

Instantly share code, notes, and snippets.

View kirich1409's full-sized avatar

Kirill Rozov kirich1409

View GitHub Profile
@Module
interface ActivityBindsModule {
@Binds
@IntoMap
@ActivityKey(MainActivity::class)
fun bindMainActivityToActivityForMultiBinding(activity: MainActivity): Activity
}
@Module
interface ComponentProvidersModule {
// Define that a Dagger Component can provide Multibind Map of Activities by class
@Multibinds
fun provideActivities(): Map<Class<out Activity>, @JvmSuppressWildcards Activity>
}
@Module
object AppModule {
@Provides
fun provideFragmentFactory(
fragmentProviders: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<Fragment>>
): FragmentFactory {
return InjectFragmentFactory(fragmentProviders)
}
}
@Component(
modules = [
AppModule::class,
ComponentProvidersModule::class,
FragmentBindsModule::class,
ActivityBindsModule::class
]
)
interface AppComponent {
class SampleApplication : Application() {
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.create()
registerActivityLifecycleCallbacks(
SetFragmentFactoryActivityCallback(appComponent.fragmentFactory)
)
class SetFragmentFactoryActivityCallback(
private val newFragmentFactory: FragmentFactory
) : EmptyActivityLifecycleCallbacks {
private val fragmentLifecycleCallbacks =
SetFragmentFactoryFragmentCallback(newFragmentFactory)
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
if (activity is FragmentActivity) {
val fragmentManager = activity.supportFragmentManager
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
>
<application
android:name=".SampleApplication"
android:appComponentFactory="com.kirich1409.android.inject.InjectComponentFactory"
tools:replace="android:appComponentFactory"
>
class InjectFragmentFactory(
private val providers: Map<String, Provider<Fragment>>
) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
return providers[className]?.get() ?: super.instantiate(classLoader, className)
}
companion object {
@RequiresApi(Build.VERSION_CODES.P)
// We still need default constructor for AppComponentFactory
class InjectComponentFactory : AppComponentFactory() {
private lateinit var application: SampleApplication
private val activityProviders: Map<String, Provider<Activity>> by lazy {
application.appComponent.activityProviders
.mapKeys { (key, _) -> key.name }
}
class MyActivity @Inject constructor(
private val dependency: Dependency
) : AppCompatActivity()
class MyFragment @Inject constructor(
private val dependency: Dependency
) : Fragment()