Status Update
Comments
sk...@gmail.com <sk...@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
yb...@google.com <yb...@google.com>
b9...@gmail.com <b9...@gmail.com> #3
yb...@google.com <yb...@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
yb...@google.com <yb...@google.com> #5
ugh we are getting two inactive calls :/, there should only be 1.
2020-06-03 14:57:59.082 10426-10426 D/COROUTINE_LIVE_DATA: onActive androidx.lifecycle.CoroutineLiveData@3ed3643
java.lang.RuntimeException
at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.kt:241)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at androidx.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
at androidx.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at androidx.lifecycle.FlowLiveDataConversions$asFlow$1$1.invokeSuspend(FlowLiveData.kt:92)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
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)
2020-06-03 14:57:59.097 10426-10426 D/COROUTINE_LIVE_DATA: onInactive androidx.lifecycle.CoroutineLiveData@3ed3643
java.lang.RuntimeException
at androidx.lifecycle.CoroutineLiveData.onInactive(CoroutineLiveData.kt:247)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:440)
at androidx.lifecycle.LiveData.removeObserver(LiveData.java:248)
at androidx.lifecycle.MediatorLiveData$Source.unplug(MediatorLiveData.java:145)
at androidx.lifecycle.MediatorLiveData.removeSource(MediatorLiveData.java:110)
at androidx.lifecycle.FlowAsLiveDataIntegrationTest$startStopImmediately$1$mediator$1$1.onChanged(FlowAsLiveDataIntegrationTest.kt:44)
at androidx.lifecycle.FlowAsLiveDataIntegrationTest$startStopImmediately$1$mediator$1$1.onChanged(FlowAsLiveDataIntegrationTest.kt:33)
at androidx.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at androidx.lifecycle.LiveDataScopeImpl$emit$2.invokeSuspend(CoroutineLiveData.kt:101)
at androidx.lifecycle.LiveDataScopeImpl$emit$2.invoke(Unknown Source:10)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:154)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at androidx.lifecycle.LiveDataScopeImpl.emit(CoroutineLiveData.kt:99)
at androidx.lifecycle.FlowLiveDataConversions$asLiveData$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:137)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:59)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:11)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:69)
at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:321)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:54)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at androidx.lifecycle.BlockRunner.maybeRun(CoroutineLiveData.kt:176)
at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.kt:243)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at androidx.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
at androidx.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at androidx.lifecycle.FlowLiveDataConversions$asFlow$1$1.invokeSuspend(FlowLiveData.kt:92)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
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)
2020-06-03 14:57:59.098 10426-10426 D/COROUTINE_LIVE_DATA: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-06-03 14:57:59.098 10426-10426 D/COROUTINE_LIVE_DATA: onInactive androidx.lifecycle.CoroutineLiveData@3ed3643
java.lang.RuntimeException
at androidx.lifecycle.CoroutineLiveData.onInactive(CoroutineLiveData.kt:247)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:440)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at androidx.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
at androidx.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at androidx.lifecycle.FlowLiveDataConversions$asFlow$1$1.invokeSuspend(FlowLiveData.kt:92)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
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)
yb...@google.com <yb...@google.com> #6
sk...@gmail.com <sk...@gmail.com> #7
Thanks for reproducer and so quick fix.
b9...@gmail.com <b9...@gmail.com> #8
Thanks! Will it land on next Lifecycle alpha release?
yb...@google.com <yb...@google.com> #9
it won't make it to the next version (the built was already cut for the postponed Android11 launch). Should go out the version after :) but meanwhile, you can try using the snapshot (androidx.dev). we don't really play w/ this codebase much so it should be fairly stable :)
ap...@google.com <ap...@google.com> #10
Branch: androidx-master-dev
commit 4a302c8fadff7fefa27c7172d77d1128a2fa8f13
Author: Yigit Boyar <yboyar@google.com>
Date: Wed Jun 03 16:53:27 2020
Handle re-entry in live data
This CL fixes a bug where LiveData would not properly handle
re-entry in its onActive method.
There are two cases:
* onActive change method was not handling re-entry, causing
it to possibly make duplicate calls to onActive/inactive.
-> Now we guard this behind a counter to handle re-entry
* dispatch when observer is added would not handle cases where
lifecycle might change state while we are dispatching the value.
-> Now we check for state again after dispatching and if it
changed, we trigger onActive again.
Bug: 157840298
Test: FlowAsLiveDataIntegrationTest, LiveDataTest
Change-Id: I4d368886288a435f65a4db7529d987d0401b25a7
M lifecycle/lifecycle-livedata-core/src/main/java/androidx/lifecycle/LiveData.java
M lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/LiveDataTest.java
M lifecycle/lifecycle-livedata-ktx/build.gradle
A lifecycle/lifecycle-livedata-ktx/src/androidTest/java/androidx.lifecycle/FlowAsLiveDataIntegrationTest.kt
yb...@google.com <yb...@google.com>
an...@gmail.com <an...@gmail.com> #11
I'm getting this same java.lang.IllegalStateException: Cancel call cannot happen without a maybeRun
exception every so often (on devices running production, but not locally during debug).
Is there some other way I can work around this (besides taking a dependency on androidx.dev)?
I have two StateFlows (The values change based on logic in background Workers)
private val _activeCycleIdFlow = MutableStateFlow(0)
private val _latestCycleIdFlow = MutableStateFlow(0)
whose results are combined
val newCycleAvailable: Flow<Boolean>
get() = _activeCycleIdFlow.combine(_latestCycleIdFlow) { a, b -> a != b }
Which is used as follows:
val newCycle: LiveData<Boolean> = cycleRepo.newCycleAvailable.asLiveData()
yb...@google.com <yb...@google.com> #12
unfortunately i cannot think of an easy way to work around this besides copying the asLiveData
code and removing the exception (it won't hurt actually, it is just consistency check to find such bugs).
Depending on which version you are in, depending on androidx.dev may not be too bad as it fairly stable library. If I were you, i would just pull in my own asLiveData :(
an...@gmail.com <an...@gmail.com> #13
an...@gmail.com <an...@gmail.com> #14
java.lang.IllegalStateException
before emitting? There isn't much else to asLiveData
.
@InternalCoroutinesApi
val newCycle: LiveData<Boolean> = liveData {
cycleRepo.newCycleAvailable
.catch {
// ignore IllegalStateException and log cause
}
.collect {
emit(it)
}
}
yb...@google.com <yb...@google.com> #15
catching exceptions thrown from the pipeline is not a great idea as it might leave it in an inconsistent state (because the code that is intended to run after it won't run). It is better to just copy it w/o the check
an...@gmail.com <an...@gmail.com> #16
Okay, I'm clearly missing something; when I open the code (ctrl+click) for asLiveData
(from FlowLiveData.kt
), it seems very simple, and I don't see any checks. This is it:
@JvmOverloads
fun <T> Flow<T>.asLiveData(
context: CoroutineContext = EmptyCoroutineContext,
timeoutInMs: Long = DEFAULT_TIMEOUT
): LiveData<T> = liveData(context, timeoutInMs) {
collect {
emit(it)
}
}
If I do the following am I not just duplicating the above?
val newCycle: LiveData<Boolean> = liveData {
cycleRepo.newCycleAvailable
.collect {
emit(it)
}
}
an...@gmail.com <an...@gmail.com> #18
Thanks. That makes more sense to me :)
an...@gmail.com <an...@gmail.com> #19
So I changed my code back to using .asLiveData()
and modified my gradle scripts to include
allprojects {
repositories {
...
maven { url 'https://androidx.dev/snapshots/builds/6603247/artifacts/repository' }
}
}
and
def lifecycle_version = "2.3.0-SNAPSHOT"
I compared the CoroutineLiveData.kt
for the different versions (alpha4, snapshot) and they are identical. I take it the fix is elsewhere? Is it publicly available? Sorry I don't normally use snapshot builds of libraries.
yb...@google.com <yb...@google.com> #20
yea the fix is actually in core.
i was recommending just removing the check for now, it won't hurt as it is more of a state check to catch these bugs.
but i'm thinking, maybe you should just move to snapshot. also a new version is coming w/ the fix soon (i think next week)
an...@gmail.com <an...@gmail.com> #21
#20,
Thank you.
fi...@colendi.com <fi...@colendi.com> #22
Does anyone have a suggestion?
Description
Component used:
androidx.lifecycle:lifecycle-livedata-ktx
androidx.lifecycle:lifecycle-runtime
androidx.lifecycle:lifecycle-runtime-ktx
androidx.lifecycle:lifecycle-livedata-ktx
androidx.lifecycle:lifecycle-viewmodel-ktx
androidx.lifecycle:lifecycle-common-java8
Version used: 2.3.0-alpha02
Devices/Android versions reproduced on: OnePlus6T, Samsungs, Xiaomis, etc.
We are using
Flow.asLiveData()
converter. We receivejava.lang.IllegalStateException: Cancel call cannot happen without a maybeRun
exceptions on production. Unable to reproduce locally. Seems like some race condition is happening in LiveData.