How to access injected properties in attachBaseContext using Hilt?

1.8k views Asked by At

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?

1

There are 1 answers

2
Nitrodon On BEST ANSWER

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