Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access injected properties in attachBaseContext using Hilt?

For the sake of changing application's default Locale, I have to get access of my WrapContext class in attachBaseContext method inside the Activity:

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject lateinit var wrapper: WrapContext

    .
    .
    .

    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(wrapper.setLocale(newBase!!))
    }
}

But as you can imagine I get nullPointerException because the field is injected after attachBaseContext is called.

Here is the WrapContext class:

@Singleton
class WrapContext @Inject constructor() {

    fun setLocale(context: Context): Context {
        return setLocale(context, language)
    }

    .
    .
    .
}

I also tried to inject WrapContext inside MyApp class so the field should be initialized when calling it inside Activity.

@HiltAndroidApp
class MyApp : Application() {
    @Inject lateinit var wrapper: WrapContext
}

attachBaseContext inside activity:

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext((applicationContext as MyApp).wrapper.setLocale(newBase!!))
}

But I still get the same error. I debugged the code and I found that applicationContext is Null in the method.

I searched online and I found the same issue someone had with dagger here. But there is no accepted answer which can maybe give me some sights to do it in hilt.

Is there a way to get this WrapContext class in the attachBaseContext method inside activity?

like image 547
mohammad fakhraee Avatar asked Oct 01 '20 16:10

mohammad fakhraee


People also ask

How to inject dependencies in Android hilt?

To inject dependencies in any class we have to add it to the Hilt tree. For fragments or activities we do it by adding the annotation @AndroidEntryPoint. Similarly we add @HiltViewModel to add a view model to the Hilt tree. Hilt doesn’t provide such annotations for all Android classes.

Can you inject runtime parameters in hilt?

Hilt: Inject Runtime parameters to ViewModels. – Carrion.dev Hilt: Inject Runtime parameters to ViewModels. Since Hilt appeared to make it easier the dependency injection in Android, it was impossible to inject runtime parameters without using third party libraries.

How do I inject a specific type into a hilt method?

In this case, you could use a Hilt module with @Provides . Both methods have the same return type, but the qualifiers label them as two different bindings: You can inject the specific type that you need by annotating the field or parameter with the corresponding qualifier: // As a dependency of another class.

How to create an instance of a class using hilt?

By using Hilt, we just tell the compiler once how to create an instance of a class and then just inject (or pass it) it anywhere. Hilt is a dependency injection library for Android that reduces the boilerplate of doing manual dependency injection in your project. Add dependency in your app’s build.gradle 2. Add plugin in your app’s build.gradle 3.


Video Answer


1 Answers

You can use an entry point to obtain dependencies from ApplicationComponent as soon as you have a Context attached to your application. Fortunately, such a context is passed into attachBaseContext:


    @EntryPoint
    @InstallIn(ApplicationComponent::class)
    interface WrapperEntryPoint {
        val wrapper: WrapContext
    }

    override fun attachBaseContext(newBase: Context) {
        val wrapper = EntryPointAccessors.fromApplication(newBase, WrapperEntryPoint::class).wrapper
        super.attachBaseContext(wrapper.setLocale(newBase))
    }
like image 147
Nitrodon Avatar answered Nov 15 '22 00:11

Nitrodon