'When using EntrypointAccessor.fromActivity, crash with "does not implement interface dagger.hilt.internal.GeneratedComponent"

Just to experiment using EntryPoint, I can connect MySubComponent to SingletonComponent as below

class SubComponentEntrypointActivity : AppCompatActivity() {
    @InstallIn(SingletonComponent::class)
    @EntryPoint
    interface MySubComponentEntryPoint {
        fun mySubComponent(): MySubComponent
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub_component_entrypoint)
        val entryPoint = EntryPointAccessors.fromApplication(applicationContext, MySubComponentEntryPoint::class.java)
        entryPoint.mySubComponent().inject(this)

    }
}

However, if I want to connect to ActivityComponent, I wrote as below

class SubComponentEntrypointActivity : AppCompatActivity() {
    @InstallIn(ActivityComponent::class) // Edit here
    @EntryPoint
    interface MySubComponentEntryPoint {
        fun mySubComponent(): MySubComponent
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub_component_entrypoint)
       // Edit here
        val entryPoint = EntryPointAccessors.fromActivity(this, MySubComponentEntryPoint::class.java)
        entryPoint.mySubComponent().inject(this)

    }
}

Then it will crash with

java.lang.RuntimeException: Unable to start activity 
ComponentInfo{com.example.multimoduledaggerhilt/com.example.multimoduledaggerhilt.entrypoint.subcomponent.SubComponentEntrypointActivity}: 
java.lang.IllegalStateException: Given component holder class 
com.example.multimoduledaggerhilt.entrypoint.subcomponent.SubComponentEntrypointActivity 
does not implement interface dagger.hilt.internal.GeneratedComponent or 
interface dagger.hilt.internal.GeneratedComponentManager

Why it crash, and how can it be fixed?



Solution 1:[1]

The reason is, when using

EntryPointAccessors.fromActivity(this, ...)

The this should be from an Activity that is annotated with @AndroidEntryPoint. Therefore, this cannot be performed within the Activity itself, but instead from another class that depends on the Activity e.g

class MyPresenter(activity: Activity) {
    @InstallIn(ActivityComponent::class)
    @EntryPoint
    interface MySubComponentEntryPoint {
        fun mySubComponent(): MySubComponent
    }

    init {
        val entryPoint = EntryPointAccessors.fromActivity(activity, MyPresenter.MySubComponentEntryPoint::class.java)
        entryPoint.mySubComponent().inject(this)
)
    }
}

where the MyPresenter is provided with an activity that need to be annotated with @AndroidEntryPoint e.g.

@AndroidEntryPoint
class SubComponentEntrypointActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub_component_entrypoint)

        MyPresenter(this)
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Elye