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

Update for Androidx Lifecycle 2.8.0 support #193

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Added extensions for `findContext` and `findActiveContext` to `NavigationContext` to allow for finding other NavigationContexts from a context reference
* Updated `NavigationContainer` to add `getChildContext` which allows finding specific Active/ActivePushed/ActivePresented/Specific contexts from a container reference
* Added `instruction` property to `NavigationContext`, and marked `NavigationContext` as `@AdvancedEnroApi`
* Added support for androidx.lifecycle `2.8.0-beta01` and the removal of setTagIfAbsent/getTag (will use addCloseable/getCloseable if it is possible)

## 2.3.0
* Updated NavigationFlow to return from `next` after `onCompleted` is called, rather than continuing to set the backstack from the flow
Expand Down
21 changes: 16 additions & 5 deletions enro-core/src/main/java/androidx/lifecycle/SetNavigationHandle.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
package androidx.lifecycle

import dev.enro.core.NavigationHandle

import java.io.Closeable

internal const val NAVIGATION_HANDLE_KEY = "dev.enro.viemodel.NAVIGATION_HANDLE_KEY"

internal class ClosableNavigationHandleReference(
navigationHandle: NavigationHandle,
) : Closeable {
var navigationHandle: NavigationHandle? = navigationHandle
override fun close() {
navigationHandle = null
}
}

internal fun ViewModel.setNavigationHandleTag(navigationHandle: NavigationHandle) {
setTagIfAbsent(
addCloseable(
NAVIGATION_HANDLE_KEY,
navigationHandle
ClosableNavigationHandleReference(navigationHandle),
)

}

internal fun ViewModel.getNavigationHandleTag(): NavigationHandle? {
return getTag<NavigationHandle>(
val closeable = getCloseable(
NAVIGATION_HANDLE_KEY
)
) as? ClosableNavigationHandleReference
return closeable?.navigationHandle
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.setNavigationHandleTag
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.MutableCreationExtras
import dev.enro.core.EnroException
import dev.enro.core.NavigationHandle
import kotlin.reflect.KClass

@PublishedApi
internal class EnroViewModelFactory(
private val navigationHandle: NavigationHandle,
private val delegate: ViewModelProvider.Factory
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
val mutableCreationExtras = MutableCreationExtras(extras)
EnroViewModelNavigationHandleProvider.put(modelClass, navigationHandle)
val viewModel = try {
delegate.create(modelClass, extras) as T
if (mutableCreationExtras[ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY] == null) {
mutableCreationExtras[ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY] = getDefaultKey(modelClass.kotlin)
}
delegate.create(modelClass, mutableCreationExtras) as T
} catch (ex: RuntimeException) {
if(ex is EnroException) throw ex
if (ex is EnroException) throw ex
throw EnroException.CouldNotCreateEnroViewModel(
"Failed to created ${modelClass.name} using factory ${delegate::class.java.name}.\n",
ex
Expand All @@ -31,4 +37,19 @@ internal class EnroViewModelFactory(
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return create(modelClass, CreationExtras.Empty)
}

companion object {
/**
* See [androidx.lifecycle.viewmodel.internal.ViewModelProviders]
*/
private const val VIEW_MODEL_PROVIDER_DEFAULT_KEY: String =
"androidx.lifecycle.ViewModelProvider.DefaultKey"

internal fun <T : ViewModel> getDefaultKey(modelClass: KClass<T>): String {
val canonicalName = requireNotNull(modelClass.qualifiedName) {
"Local and anonymous classes can not be ViewModels"
}
return "${VIEW_MODEL_PROVIDER_DEFAULT_KEY}:$canonicalName"
}
}
}
6 changes: 3 additions & 3 deletions libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ androidx-navigation-ui = "androidx.navigation:navigation-ui-ktx:2.7.7"
androidx-activity = "androidx.activity:activity-ktx:1.9.0"
compose-activity = "androidx.activity:activity-compose:1.9.0"

androidx-lifecycle = "androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0"
androidx-lifecycle-process = "androidx.lifecycle:lifecycle-process:2.7.0"
compose-viewmodel = "androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0"
androidx-lifecycle = "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0-beta01"
androidx-lifecycle-process = "androidx.lifecycle:lifecycle-process:2.8.0-beta01"
compose-viewmodel = "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0-beta01"

compose-compiler = "androidx.compose.compiler:compiler:1.5.12"
compose-foundation = "androidx.compose.foundation:foundation:1.6.6"
Expand Down
Loading