Status Update
Comments
da...@gmail.com <da...@gmail.com> #2
Branch: androidx-master-dev
commit b90079595f33f58fece04026a97faa0d243acdb1
Author: Yuichi Araki <yaraki@google.com>
Date: Wed Sep 18 16:55:49 2019
Change the way to detect mismatch between POJO and query
This fixes cursor mismatch warnings with expandProjection.
Bug: 140759491
Test: QueryMethodProcessorTest
Change-Id: I7659002e5e0d1ef60fc1af2a625c0c36da0664d8
M room/compiler/src/main/kotlin/androidx/room/processor/QueryMethodProcessor.kt
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
M room/compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
M room/compiler/src/test/kotlin/androidx/room/testing/TestProcessor.kt
co...@gmail.com <co...@gmail.com> #3
cl...@google.com <cl...@google.com>
an...@google.com <an...@google.com> #4
Branch: androidx-master-dev
commit bdde5a1a970ddc9007b28de4aa29d60ffa588f08
Author: Yigit Boyar <yboyar@google.com>
Date: Thu Apr 16 16:47:05 2020
Re-factor how errors are dismissed when query is re-written
This CL changes how we handle errors/warnings if query is
re-written.
There was a bug in expandProjection where we would report warnings
for things that Room already fixes automatically (
The solution to that problem (I7659002e5e0d1ef60fc1af2a625c0c36da0664d8)
solved it by deferring validating of columns until after re-write
decision is made. Unfortunately, this required changing PojoRowAdapter
to have a dummy mapping until it is validating, make it hard to use
as it does have a non-null mapping which is not useful.
This CL partially reverts that change and instead rely on the log
deferring logic we have in Context. This way, we don't need to break
the stability of PojoRowAdapter while still having the ability to
drop warnings that room fixes. This will also play nicer when we
have different query re-writing options that can use more information
about the query results.
Bug: 153387066
Bug: 140759491
Test: existing tests pass
Change-Id: I2ec967c763d33d7a3ff02c1a13c6953b460d1e5f
M room/compiler/src/main/kotlin/androidx/room/log/RLog.kt
M room/compiler/src/main/kotlin/androidx/room/processor/QueryMethodProcessor.kt
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
da...@gmail.com <da...@gmail.com> #5
Good guess I'm indeed using navigation. The above workaround fixes it for me.
co...@gmail.com <co...@gmail.com> #6
I am also using navigation.
The provided workaround doesn't restore the mutation policy of the MutableState object.
an...@google.com <an...@google.com> #7
This one will save/restore the mutation policy as well:
fun <T> stateSaver() = listSaver<MutableState<T>, Any>(
save = { state ->
listOf(
state.value ?: "null",
when ((state as SnapshotMutableState).policy) {
structuralEqualityPolicy<T>() -> 0
referentialEqualityPolicy<T>() -> 1
neverEqualPolicy<T>() -> 2
else -> throw IllegalStateException("Mutation policy is not supported")
}
)
},
restore = {
val value = it[0]
val policy = when (it[1]) {
0 -> structuralEqualityPolicy<T>()
1 -> referentialEqualityPolicy<T>()
else -> neverEqualPolicy<T>()
}
@Suppress("UNCHECKED_CAST")
mutableStateOf((if (value == "null") null else value) as T, policy)
}
)
co...@gmail.com <co...@gmail.com> #8
What did you think of my solution that uses the init() function passed to the rememberSaveable()? This prevents needing to save anything about the policy and would support any mutation policy.
I'm not sure if the docs say anywhere that the init() function will only be called the first time and using it to restore the state would be incorrect.
I've been using my workaround fairly extensively and it has been great.
an...@google.com <an...@google.com> #9
Yes, this also works. Feel free to use it until we provide the correct fix in the library
ap...@google.com <ap...@google.com> #10
Branch: androidx-main
commit dd000ea5e6eb3a8f07b869595ca62aa2fb781d12
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Mon Feb 22 19:42:13 2021
Fix for broken rememberSaveable { mutableStateOf(0) } with navigation-compose
Previously we were converting MutableState into a parcelable structure only for a direct child of the saving list. It was incorrect as SaveableStateHolder used in navigation is wrapping the state of the screen as a value into a Map. Now we will recursively iterate through List/Maps and covert all inner MutableState objects.
Fixes: 180042685
Fixes: 180701630
Test: new tests in ActivityRecreationTest
Relnote: Fix for broken rememberSaveable { mutableStateOf(0) } when used inside a destination of navigation-compose.
Change-Id: I1312b5b210dde32250945d164a2f3a1b574cb0a8
M compose/runtime/runtime-saveable/src/androidAndroidTest/AndroidManifest.xml
M compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
M compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/RememberSaveable.kt
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistry.android.kt
an...@google.com <an...@google.com> #11
ba...@gmail.com <ba...@gmail.com> #12
It looks like this bug has been re-introduced in 1.0
an...@google.com <an...@google.com> #13
el...@kroger.com <el...@kroger.com> #14
Hi I am seeing this same issue using navigation-compose version 2.5.2, we tried the suggestions from this thread from 2021 but they did not work. The stack trace looks like this:
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = [Landroidx.compose.runtime.MutableState;)
at android.os.Parcel.writeSerializable(Parcel.java:1833)
at android.os.Parcel.writeValue(Parcel.java:1780)
at android.os.Parcel.writeList(Parcel.java:1045)
at android.os.Parcel.writeValue(Parcel.java:1729)
at android.os.Parcel.writeMapInternal(Parcel.java:896)
at android.os.Parcel.writeMap(Parcel.java:878)
at android.os.Parcel.writeValue(Parcel.java:1694)
at android.os.Parcel.writeMapInternal(Parcel.java:896)
at android.os.Parcel.writeMap(Parcel.java:878)
at android.os.Parcel.writeValue(Parcel.java:1694)
at android.os.Parcel.writeList(Parcel.java:1045)
at android.os.Parcel.writeValue(Parcel.java:1729)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
...
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4505)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.io.NotSerializableException: androidx.compose.runtime.ParcelableSnapshotMutableState
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1434)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1230)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
at android.os.Parcel.writeSerializable(Parcel.java:1828)
at android.os.Parcel.writeValue(Parcel.java:1780)
at android.os.Parcel.writeList(Parcel.java:1045)
at android.os.Parcel.writeValue(Parcel.java:1729)
at android.os.Parcel.writeMapInternal(Parcel.java:896)
at android.os.Parcel.writeMap(Parcel.java:878)
...
an...@google.com <an...@google.com> #15
If you can file a new bug with the reproducible code sample we will be able to take a look
ga...@gmail.com <ga...@gmail.com> #16
E FATAL EXCEPTION: main
Process: com.example.animeapp, PID: 12273
java.lang.RuntimeException: Parcel: unable to marshal value Color(0.83137256, 0.75686276, 0.8156863, 1.0, sRGB IEC61966-2.1)
at android.os.Parcel.writeValue(Parcel.java:1885)
at android.os.Parcel.writeList(Parcel.java:1092)
at android.os.Parcel.writeValue(Parcel.java:1832)
at android.os.Parcel.writeList(Parcel.java:1092)
at android.os.Parcel.writeValue(Parcel.java:1832)
at android.os.Parcel.writeMapInternal(Parcel.java:943)
at android.os.Parcel.writeMap(Parcel.java:925)
at android.os.Parcel.writeValue(Parcel.java:1797)
at android.os.Parcel.writeMapInternal(Parcel.java:943)
at android.os.Parcel.writeMap(Parcel.java:925)
at android.os.Parcel.writeValue(Parcel.java:1797)
at android.os.Parcel.writeList(Parcel.java:1092)
at android.os.Parcel.writeValue(Parcel.java:1832)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1044)
at android.os.Parcel.writeValue(Parcel.java:1801)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1044)
at android.os.Parcel.writeValue(Parcel.java:1801)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4389)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
an...@google.com <an...@google.com> #17
ma...@marcardar.com <ma...@marcardar.com> #18
Related to this issue, it would be useful to give more details in the log message, because when, for example, the object is a Set
we have no idea what is the underlying type (the type of the items stored in the Set
) and so have no idea where to look in the code:
Fatal Exception: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = java.util.LinkedHashSet)
at android.os.Parcel.writeSerializable(Parcel.java:2178)
at android.os.Parcel.writeValue(Parcel.java:1944)
at androidx.compose.runtime.ParcelableSnapshotMutableState.writeToParcel(ParcelableSnapshotMutableState.kt:30)
at android.os.Parcel.writeParcelable(Parcel.java:1965)
at android.os.Parcel.writeValue(Parcel.java:1871)
at android.os.Parcel.writeList(Parcel.java:1153)
at android.os.Parcel.writeValue(Parcel.java:1893)
at android.os.Parcel.writeMapInternal(Parcel.java:1004)
at android.os.Parcel.writeMap(Parcel.java:986)
at android.os.Parcel.writeValue(Parcel.java:1858)
at android.os.Parcel.writeMapInternal(Parcel.java:1004)
at android.os.Parcel.writeMap(Parcel.java:986)
at android.os.Parcel.writeValue(Parcel.java:1858)
at android.os.Parcel.writeList(Parcel.java:1153)
at android.os.Parcel.writeValue(Parcel.java:1893)
at android.os.Parcel.writeMapInternal(Parcel.java:1004)
at android.os.Parcel.writeMap(Parcel.java:986)
at android.os.Parcel.writeValue(Parcel.java:1858)
at android.os.Parcel.writeList(Parcel.java:1153)
at android.os.Parcel.writeValue(Parcel.java:1893)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:1036)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1304)
at android.os.Parcel.writeBundle(Parcel.java:1105)
at android.os.Parcel.writeValue(Parcel.java:1862)
at android.os.BaseBundle.dumpStats(BaseBundle.java:1690)
at android.os.BaseBundle.dumpStats(BaseBundle.java:1727)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:150)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8751)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
il...@google.com <il...@google.com> #19
Re
Description
Component used: Compose Version used: 1.0.0-alpha12 Devices/Android versions reproduced on: Pixel 4 Android 11
The recommended code to replace
savedInstanceState{ 0 }
isrememberSaveable { mutableStateOf(0) }
However, I've found this causes a crash whenever the app is minimized.
The exception thrown is
java.lang.RuntimeException: Parcel: unable to marshal value androidx.compose.runtime.SnapshotMutableStateImpl@5a847c2
After digging into the code I believe this is caused by the special version of
rememberSaveable
forMutableState
objects doesn't have a default saver parameter so the normal version is used which doesn't know how to save aMutableState
.I think changing the
rememberSaveable
definition fromto
would fix this.