Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Manually regenerate application component #4295

Closed
marcorighini opened this issue May 1, 2024 · 1 comment
Closed

Feature request: Manually regenerate application component #4295

marcorighini opened this issue May 1, 2024 · 1 comment

Comments

@marcorighini
Copy link

We need to regenerate the application component manually on logout (i.e. the singleton dependencies).

This is due to several singleton dependencies with state variables related to the logged-in user. This makes it hard and error-prone to follow solutions like resetting those dependencies or using custom components (this would also require writing all the boilerplate associated with entrypoints).

Investigating the generated Hilt code we found that the following code would provide such a feature

@HiltAndroidApp
class LogApplication : Application() {

    @Inject
    internal lateinit var dependency: LoggerInMemoryDataSource

    override fun onCreate() {
        super.onCreate()
        logout()
    }

    @Suppress("CAST_NEVER_SUCCEEDS")
    private fun regenerateComponent() {
        Log.d("", "Before: $dependency")

        val cm = (this as GeneratedComponentManagerHolder).componentManager()
        val f = ApplicationComponentManager::class.java.declaredFields.find { it.name == "component" }
        f?.let {
            it.isAccessible = true
            f.set(cm, null)
        }
        ((this as GeneratedComponentManager<ApplicationComponentManager>)
            .generatedComponent() as LogApplication_GeneratedInjector)
            .injectLogApplication(UnsafeCasts.unsafeCast(this))

        Log.d("", "After: $dependency")
    }

    fun logout() {
        regenerateComponent()
    }
}

We tested it and LoggerInMemoryDataSource (a singleton) reference is changing.

Our questions are the following:

  • do you see any drawback of the previous solution apart from the need for testing on every Hilt upgrade?
  • the feature does not seem so hard to support by Hilt, does it make sense to provide it officially? The use case should not be so uncommon.

Thanks!

@marcorighini marcorighini changed the title Feature request: Manually regenerate application component Feature request: Manually generate application component May 1, 2024
@marcorighini marcorighini changed the title Feature request: Manually generate application component Feature request: Manually regenerate application component May 1, 2024
@Chang-Eric
Copy link
Member

I don't think we can add this as a feature to Hilt since it basically subverts the notion of what @Singleton means since now those objects can be instantiated more than once (and you could have multiple instances still around if something else is holding on to the previous instance).

For your particular solution, besides the obvious issue of this reflecting on internal Hilt implementation details that aren't guaranteed, you should be careful about code obfuscation. Also, as alluded to above, this doesn't change that existing things may already have references to the old component that won't be dropped. So any existing activity, fragment, service, etc, won't be updated immediately. You might be fine with that, but you may also consider that weird things can happen on configuration change. For example, if the ApplicationComponent is switched and then a configuration change happens, the new activity would use the new ApplicationComponent while any ViewModel created before that would not because ViewModels are retained through configuration change. This could cause unexpected situations since your Activity would be using different singletons than your ViewModel. So overall, I wouldn't recommend this pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants