Issue
I just begin to try to use Hilt on my very simple project. For now it was all on Dagger2 but I would like to migrate to Hilt.
I have an activity :
@AndroidEntryPoint
class MainActivity : BaseActivity() {
// SOME STUFF
}
And a BaseActivity like this :
abstract class BaseActivity : AppCompatActivity() {
// SOME STUFF
}
Also, I have a class using the baseActivity to display a dialog. For example :
@FragmentScoped
class TestComponentImpl @Inject constructor(
private val baseActivity: BaseActivity
) : TestComponent {
override fun displayDialog() {
MaterialDialog(baseActivity).show { ...
}
}
However, when I try to compile, I have this error :
BaseActivity cannot be provided without an @Provides-annotated method.
So, my question is : How to constructor inject an abstract class. I tried a lot of things but without success, like this in a Hilt module :
@Provides
@Singleton
fun provideBaseActivity(): BaseActivity{
return BaseActivity() // Of course, it can't work cause it's an abstract class
}
OR (like I did with Dagger) :
@Provides
@PerActivity
fun appCompatActivity(baseActivity: BaseActivity) = baseActivity as AppCompatActivity
Also, I'm just a beginner with Hilt so, maybe I miss something. I will keep on search :)
Thanks for your time and your answers :)
EDIT :
I searched on my own during few days and this seems to work but doesn't seem really good ...
@Singleton
@Provides
fun provideBaseActivity(baseActivity: BaseActivity): AppCompatActivity {
return baseActivity
}
But only if I put my baseActivity like this :
open class BaseActivity Inject constructor() : AppCompatActivity()
However, after that, if I try to use my injected baseActivity in my TestComponentImpl like this (like I was doing with Dagger before Hilt):
override fun displayError() {
Snackbar.make(
baseActivity.findViewById(android.R.id.content),
"My error text",
Snackbar.LENGTH_LONG
).apply {
show()
}
I've got another error :
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
So I don't think my baseActivity injection is fully well done. I'm keeping to investigate ;)
Solution
A bit hacky (type-casting) but should work (untested, writing off the top of my head so feel free to let me know if something isn't working as expected):
Create such Module
:
@Module
@InstallIn(ActivityComponent::class)
object BaseActivityModule {
@Provides
fun provideBaseActivity(activity: Activity): BaseActivity {
check(activity is BaseActivity) { "Every Activity is expected to extend BaseActivity" }
return activity as BaseActivity
}
}
The last cast as BaseActivity
is probably unnecessary. Kotlin compiler should handle this.
Answered By - Bartek Lipinski
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.