Skip to content

Commit

Permalink
fix activity leak after configuration change, second way
Browse files Browse the repository at this point in the history
  • Loading branch information
shpasha committed May 18, 2024
1 parent 9c96bbe commit 7ef7e44
Showing 1 changed file with 6 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package cafe.adriel.voyager.androidx

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.ContextWrapper
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
Expand Down Expand Up @@ -52,7 +50,7 @@ public class AndroidScreenLifecycleOwner private constructor() :

override val viewModelStore: ViewModelStore = ViewModelStore()

private val atomicContext = AtomicReference<Context>()
private val atomicAppContext = AtomicReference<Context>()
internal val atomicParentLifecycleOwner = AtomicReference<LifecycleOwner>()

private val controller = SavedStateRegistryController.create(this)
Expand All @@ -64,13 +62,13 @@ public class AndroidScreenLifecycleOwner private constructor() :

override val defaultViewModelProviderFactory: ViewModelProvider.Factory
get() = SavedStateViewModelFactory(
application = atomicContext.get()?.applicationContext?.getApplication(),
application = atomicAppContext.get()?.getApplication(),
owner = this
)

override val defaultViewModelCreationExtras: CreationExtras
get() = MutableCreationExtras().apply {
val application = atomicContext.get()?.applicationContext?.getApplication()
val application = atomicAppContext.get()?.getApplication()
if (application != null) {
set(AndroidViewModelFactory.APPLICATION_KEY, application)
}
Expand Down Expand Up @@ -125,9 +123,6 @@ public class AndroidScreenLifecycleOwner private constructor() :
}

override fun onDispose(screen: Screen) {
val context = atomicContext.getAndSet(null) ?: return
val activity = context.getActivity()
if (activity != null && activity.isChangingConfigurations) return
viewModelStore.clear()
disposeEvents.forEach { event ->
lifecycle.safeHandleLifecycleEvent(event)
Expand All @@ -140,7 +135,7 @@ public class AndroidScreenLifecycleOwner private constructor() :

@Composable
private fun getHooks(): List<ProvidedValue<*>> {
atomicContext.compareAndSet(null, LocalContext.current)
atomicAppContext.compareAndSet(null, LocalContext.current.applicationContext)
atomicParentLifecycleOwner.compareAndSet(null, LocalLifecycleOwner.current)

return remember(this) {
Expand Down Expand Up @@ -210,15 +205,8 @@ public class AndroidScreenLifecycleOwner private constructor() :
}
}

private tailrec fun Context.getActivity(): Activity? = when (this) {
is Activity -> this
is ContextWrapper -> baseContext.getActivity()
else -> null
}

private tailrec fun Context.getApplication(): Application? = when (this) {
private fun Context.getApplication(): Application? = when (this) {
is Application -> this
is ContextWrapper -> baseContext.getApplication()
else -> null
}

Expand Down Expand Up @@ -248,6 +236,7 @@ public class AndroidScreenLifecycleOwner private constructor() :
private val disposeEvents = arrayOf(
Lifecycle.Event.ON_DESTROY
)

public fun get(screen: Screen): ScreenLifecycleOwner {
return ScreenLifecycleStore.get(screen) { AndroidScreenLifecycleOwner() }
}
Expand Down

0 comments on commit 7ef7e44

Please sign in to comment.