Status Update
Comments
jb...@google.com <jb...@google.com>
il...@google.com <il...@google.com> #2
ed...@gmail.com <ed...@gmail.com> #3
since it is already marked as deprecated, we can probably do it by now.
il...@google.com <il...@google.com> #4
cl...@google.com <cl...@google.com>
ap...@google.com <ap...@google.com> #5
Branch: androidx-master-dev
commit d576cbdc911cba16638a44fd8223391a90a07ef7
Author: Mike Nakhimovich <digitalbuddha@users.noreply.github.com>
Date: Tue Aug 11 09:30:34 2020
[GH] Hide deprecated internal API.
## Proposed Changes
* `RoomDatabase.java` has protected `mCallbacks` field which is leaking in the API docs, we should @Hide it.
## Testing
Test: Ran unit tests locally
## Issues Fixed
Fixes: 76109329
This is an imported pull request from
Resolves #61
Github-Pr-Head-Sha: 6440daa3a63752c7f9d5ba2a390248cd85bc634f
GitOrigin-RevId: fe92d8466a59b44b218b6ca3cbd57dcda17992f7
Change-Id: Id599cdf5b02b32bdae0166266fb7da967598fe92
A room/runtime/api/current.ignore
M room/runtime/api/current.txt
M room/runtime/api/public_plus_experimental_current.txt
M room/runtime/api/restricted_current.txt
M room/runtime/src/main/java/androidx/room/RoomDatabase.java
cl...@google.com <cl...@google.com> #6
Fixed internally and will be available in navigation 2.8.0-beta01
ed...@gmail.com <ed...@gmail.com> #7
pr...@google.com <pr...@google.com> #8
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.navigation:navigation-common:2.8.0-beta01
androidx.navigation:navigation-compose:2.8.0-beta01
je...@gmail.com <je...@gmail.com> #9
This seems to be still be busted (same error) if you change isNullableAllowed = true (I don't have any errors when changing the same code to isNullableAllowed = false AND <IndividualId>)
Example:
Custom Class
@JvmInline
@Serializable
value class IndividualId(val value: String)
NavType for nullable:
val IndividualIdNullableNavType = object : NavType<IndividualId?>(
isNullableAllowed = true
) {
override fun get(bundle: Bundle, key: String): IndividualId? = bundle.getString(key)?.let { IndividualId(it) }
override fun put(bundle: Bundle, key: String, value: IndividualId?) {
value?.let { bundle.putString(key, it.value) }
}
override fun parseValue(value: String): IndividualId? {
if (value == "null") return null
return Json.decodeFromString<IndividualId>(value)
}
override fun serializeAsValue(value: IndividualId?): String = value?.let { Json.encodeToString(IndividualId.serializer(), it) } ?: ""
}
NavHost code:
composable<IndividualEditRoute>(mapOf(
typeOf<IndividualId?>() to IndividualIdNullableNavType,
)) { backStackEntry ->
Log.w("TEST", "Before") // prints
val individualEditRoute = backStackEntry.toRoute<IndividualEditRoute>()
Log.w("TEST", "After: individualEditRoute == $individualEditRoute") // never gets here because: ClassCastException: IndividualId cannot be cast to java.lang.String
IndividualEditScreen(navController)
}
The following works (no error):
onClick = {
navController.navigate(IndividualEditRoute())
},
The following will cause a "ClassCastException: IndividualId cannot be cast to java.lang.String"
onClick = {
navController.navigate(IndividualEditRoute(IndividualId("123")))
},
cl...@google.com <cl...@google.com> #11
Re
ga...@gmail.com <ga...@gmail.com> #12
I'm also having this issue. I have created a repo for showcasing this:
In there you will find another case with a Parcelable object. In my case is quite strange since the logcat shows this error:
Process: com.bobbyesp.navigationbugreport, PID: 23169
kotlinx.serialization.SerializationException: Serializer for class 'Companion' is not found.
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:278)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source:1)
at androidx.navigation.NavGraph.setStartDestination(NavGraph.kt:404)
cl...@google.com <cl...@google.com> #13
Re
But based on your source code, it is your startDestination in song
arg for your SongInformationPage
.
With safe args, you can conveniently pass in starting arguments by passing in a class instance. The arguments will automatically be available within the starting composable.
This means your nested graph should be
navigation<UtilitiesNavigator>(
startDestination = SongInformationPage(song = ...),
)
If your startDestination does not contain arguments, then you can pass in either:
@Serializable
object MyDestination
startDestination = MyDestination
--- OR ---
@Serializable
class MyDestination
startDestination = MyDestination::class
If you have further questions, please file a separate bug so it is easier for other users with the same question to locate the answer.
ga...@gmail.com <ga...@gmail.com> #14
du...@matechmobile.com <du...@matechmobile.com> #15
here is my code for you guys to look around:
fun setNavController(mNavController: NavController) {
this.navController = mNavController
navController.graph = navController.createGraph(startDestination = nav_routes.manual_add_otp_data) {
fragment<AddOtpManualFragment, AddOtpData>(
typeMap = mapOf(typeOf<AddOtpData>() to getCustomParametersType<AddOtpData>())
) {
label = nav_routes.manual_add_otp_data
}
}
}
--------
private inline fun <reified T : Parcelable> getCustomParametersType(nullable: Boolean = false) =
object : NavType<T>(
isNullableAllowed = nullable
) {
override fun put(bundle: Bundle, key: String, value: T) {
// Handle null case if the type is nullable
bundle.putParcelable(key, value)
}
override fun get(bundle: Bundle, key: String): T? {
// Return null if the value is nullable and not present
return if (isNullableAllowed) {
bundle.getParcelable(key)
} else {
bundle.getParcelable(key)
?: throw IllegalArgumentException("No value present for non-nullable type")
}
}
override fun parseValue(value: String): T {
// Decode and deserialize the string into the object
return Json.decodeFromString(value)
}
override fun serializeAsValue(value: T): String {
// Encode the object into a JSON string and Uri encode it
return Uri.encode(Json.encodeToString(value))
}
}
---------
@Serializable
@Parcelize
data class AddOtpData(val otpAuthDB: OtpAuthDB) : Parcelable
that all, thanks
Description
Version used: 2.8.0-alpha08
Devices/Android versions reproduced on: Pixel 6a (Android 14)
Getting the custom arg in a ViewModel when using just serializables instead of parcelables with this NavType:
val bookType = object : NavType<Book>(isNullableAllowed = false) {
override fun get(bundle: Bundle, key: String): Book? {
return bundle.getString(key)?.let { Json.decodeFromString<Book>(it) }
}
override fun parseValue(value: String) = Json.decodeFromString<Book>(value)
override fun serializeAsValue(value: Book): String = Json.encodeToString(value)
override fun put(bundle: Bundle, key: String, value: Book) {
bundle.putString(key, Json.encodeToString(value))
}
}
It works well if I get the value from the NavBackStackEntry but if I do this in the ViewModel:
val bookDetail = savedStateHandle.toRoute<BookDetail>()
I get this error when navigating to the detail:
java.lang.ClassCastException: java.lang.String cannot be cast to com.example.composenavigation.typesafety.Book
You can see an example in:
The navigation is in the file: TypeSafetyNavigation.kt
Thanks in advance!