akexorcist / Localization

[Android] In-app language changing library
Apache License 2.0
983 stars 154 forks source link

Crash - Could not find an Application in the given context [ Android Hilt ] #137

Closed PearlDroidOs closed 2 years ago

PearlDroidOs commented 2 years ago

I found this crash as below:

Caused by: java.lang.IllegalStateException: Could not find an Application in the given context: android.app.ContextImpl@721ad02
        at dagger.hilt.android.internal.Contexts.getApplication(Contexts.java:42)
        at dagger.hilt.android.EntryPointAccessors.fromApplication(EntryPointAccessors.java:37)
        at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager$1.create(ActivityRetainedComponentManager.java:101)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager.createComponent(ActivityRetainedComponentManager.java:123)
        at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager.generatedComponent(ActivityRetainedComponentManager.java:115)
        at dagger.hilt.android.internal.managers.ActivityRetainedComponentManager.generatedComponent(ActivityRetainedComponentManager.java:44)
        at dagger.hilt.EntryPoints.get(EntryPoints.java:59)
        at dagger.hilt.android.internal.managers.ActivityComponentManager.createComponent(ActivityComponentManager.java:86)
        at dagger.hilt.android.internal.managers.ActivityComponentManager.generatedComponent(ActivityComponentManager.java:66)
        at com.{package}.Hilt_BActivity.generatedComponent(Hilt_BActivity.java:40)
        at com.{package}.Hilt_BActivity.inject(Hilt_BActivity.java:62)
        at com.{package}.Hilt_BActivity$1.onContextAvailable(Hilt_BActivity.java:33)
        at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)
        at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:320)
        at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:249)
        at com.akexorcist.localizationactivity.ui.LocalizationActivity.onCreate(LocalizationActivity.kt:24)
        at com.{package}.BaseActivity.onCreate(BaseActivity.kt:20)
        at com.{package}.BActivity.onCreate(BActivity.kt:20)

when I implement something like this:

@HiltAndroidApp
class MainApplication : Application() {

    private val localizationDelegate by lazy { LocalizationApplicationDelegate() }

    override fun attachBaseContext(base: Context) {
        localizationDelegate.setDefaultLanguage(base, Locale("th", "TH"))
        super.attachBaseContext(localizationDelegate.attachBaseContext(base))
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        localizationDelegate.onConfigurationChanged(this)
    }

    override fun getApplicationContext(): Context {
        return localizationDelegate.getApplicationContext(super.getApplicationContext())
    }
}

===========================================================
//This class is legacy class that has not been migrated to use Android Hilt yet
class AActivity: BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setLanguageApp("TH")
    }
}

===========================================================
//This activity is for check language changed
@AndroidEntryPoint
class BActivity: BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) // <---- Crash

    }
}

===========================================================
abstract class BaseActivity : LocalizationActivity(), OnLocaleChangedListener {
    private val localizationDelegate = LocalizationActivityDelegate(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        localizationDelegate.addOnLocaleChangedListener(this)
        localizationDelegate.onCreate()
        super.onCreate(savedInstanceState) // <-- Crash at LocalizationActivity
    }

    public override fun onResume() {
        super.onResume()
        localizationDelegate.onResume(this)
    }

    override fun attachBaseContext(newBase: Context) {
        applyOverrideConfiguration(localizationDelegate.updateConfigurationLocale(newBase))
        super.attachBaseContext(newBase)
    }

    override fun getApplicationContext(): Context {
        return localizationDelegate.getApplicationContext(super.getApplicationContext())
    }

    override fun getResources(): Resources {
        return localizationDelegate.getResources(super.getResources())
    }

    fun setLanguageApp(language: String) {
        localizationDelegate.setLanguage(this, language)
    }
}

I set language into "AActivity" and then I navigate to "BActivity" for checking new language but I got the crash that happens at "onCreate" at "BActivity" which link to "LocalizationActivity" as above.

Can you help me with how can I handle and solve it please?

Please feel free to ask if you have more question. Thank you so much 🙏🏻

sami2272 commented 2 years ago

Facing same issue. Can anyone solve this issue?

Faisal-Naseer commented 2 years ago

try not to use delegate extend your Application class with LocalizationApplication() ... and override the method

override fun getDefaultLanguage(context: Context) = Locale.ENGLISH

as documented .

akexorcist commented 2 years ago

Since AndroidX AppCompat has per-app language preferences for backward compatibility. Please migrate this library to AndroidX for more stability, compatibility, and longer support from Google team.

See Migrate to AndroidX guide

Thank you for your support