Fixed
Status Update
Comments
yb...@google.com <yb...@google.com> #2
The problem is reproducible using support lib 26.1.0, this is the updated activity:
class LiveDataTestActivity : AppCompatActivity() {
private val myLiveData = MutableLiveData<Int>().apply { value = 0 }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val textView = TextView(this).apply {
text = "AAAA"
setOnClickListener {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
type = "text/plain"
}
startActivityForResult(sendIntent, 123)
}
}
setContentView(textView)
myLiveData.observe(this, Observer<Int> {
textView.text = it.toString()
})
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
myLiveData.value = (myLiveData.value ?: 0) + 1
println("Value ${myLiveData.value}")
}
override fun onResume() {
super.onResume()
println("resume ${lifecycle.currentState}")
}
}
class LiveDataTestActivity : AppCompatActivity() {
private val myLiveData = MutableLiveData<Int>().apply { value = 0 }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val textView = TextView(this).apply {
text = "AAAA"
setOnClickListener {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
type = "text/plain"
}
startActivityForResult(sendIntent, 123)
}
}
setContentView(textView)
myLiveData.observe(this, Observer<Int> {
textView.text = it.toString()
})
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
myLiveData.value = (myLiveData.value ?: 0) + 1
println("Value ${myLiveData.value}")
}
override fun onResume() {
super.onResume()
println("resume ${lifecycle.currentState}")
}
}
vn...@gmail.com <vn...@gmail.com> #3
thanks for the reports.
After further investigation:
good news, this is not a very serious bug, it recovers right after onResume. (also the bug does not happen in latest versions of the OS)
bad news, properly fixing it requires changes in the support library so it may not catch 1.0.0 release.
details:
Lifecycles moves state to CREATED when onSavedInstanceState is called. This is done because FragmentManager disables fragment transactions when onSavedInstanceState is called. Lifecycles API guaratees that you can run a fragment transaction inside an observer. This behavior is usually fine because onSavedInstanceState is always followed by onStop.
Turns out, this is not the case for API21..
things to do:
* make sure we have tests that fragments are handled properly and observers don't receive an unexpected STARTED event.
* in the next support lib version, make sure the state is set to at least STARTED when FragmentController#noteStateNotSaved is called.
After further investigation:
good news, this is not a very serious bug, it recovers right after onResume. (also the bug does not happen in latest versions of the OS)
bad news, properly fixing it requires changes in the support library so it may not catch 1.0.0 release.
details:
Lifecycles moves state to CREATED when onSavedInstanceState is called. This is done because FragmentManager disables fragment transactions when onSavedInstanceState is called. Lifecycles API guaratees that you can run a fragment transaction inside an observer. This behavior is usually fine because onSavedInstanceState is always followed by onStop.
Turns out, this is not the case for API21..
things to do:
* make sure we have tests that fragments are handled properly and observers don't receive an unexpected STARTED event.
* in the next support lib version, make sure the state is set to at least STARTED when FragmentController#noteStateNotSaved is called.
yb...@google.com <yb...@google.com> #4
Fabio, thanks for the bug report and example code. We have a fix in the works that will update the TextView on 5.0 (the problem actually existed on 6.0 and below) just like it should on 6.0.
However, note that on 6.0 and below your onResume method will continue to print "CREATED" as Yigit mentioned above.
Thanks again!
However, note that on 6.0 and below your onResume method will continue to print "CREATED" as Yigit mentioned above.
Thanks again!
vn...@gmail.com <vn...@gmail.com> #5
reopened. fix for live data is in but the greater fix to make lifecycles consistent is still not merged.
vn...@gmail.com <vn...@gmail.com> #6
Norm
yb...@google.com <yb...@google.com> #7
Fragment ransaction bug:
UncaughtException
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:4937)
at android.view.ViewGroup.addView(ViewGroup.java:4768)
at android.view.ViewGroup.addView(ViewGroup.java:4708)
at android.view.ViewGroup.addView(ViewGroup.java:4681)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1425)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1750)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1819)
at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:855)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2587)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2377)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2239)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
UncaughtException
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:4937)
at android.view.ViewGroup.addView(ViewGroup.java:4768)
at android.view.ViewGroup.addView(ViewGroup.java:4708)
at android.view.ViewGroup.addView(ViewGroup.java:4681)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1425)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1750)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1819)
at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:855)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2587)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2377)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2239)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
yb...@google.com <yb...@google.com>
yb...@google.com <yb...@google.com> #8
we can probably tie this to WAL support.
be...@google.com <be...@google.com> #9
So the title of this bug should be changed to "support multiple instances of RoomDatabase"?
yb...@google.com <yb...@google.com>
xm...@gmail.com <xm...@gmail.com> #10
When support this? i face the same problem, it multiple query and insert, it'll block
yb...@google.com <yb...@google.com> #11
hopefully we'll have this in 2.1 . What is your use case, are you accessing the same database from different processes or are you creating 2 instance of the same RoomDatabase in the same process?
xm...@gmail.com <xm...@gmail.com> #12
Create one instance of RoomDatabase, and use LiveData paging query the datas and when querying, i also use the db connect insert the data, the query always wait the insert end and return
xm...@gmail.com <xm...@gmail.com> #13
BTW, other thread insert the data, or update the data
yb...@google.com <yb...@google.com> #14
if you are in the same process, don't use multiple RoomDatabase instances.
xm...@gmail.com <xm...@gmail.com> #15
Why the LiveData been blocked? the query always waiting for the insert end and return
ap...@google.com <ap...@google.com> #16
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 41bbdfb46058e7ef3ea6aa21ac8d7a3c7642fa1d
Author: Yuichi Araki <yaraki@google.com>
Date: Wed May 23 17:38:58 2018
Multi-instance invalidation
Developers can now sync observers for InvalidationTracker and LiveData
between multiple RoomDatabase instances by
RoomDatabase.Builder.enableMultiInstanceInvalidation(). This can also be
used for database instances in other processes. All the instances have
to be using the same database file.
When multi-instance invalidation is turned on, all the tables are
observed by an instance of MultiInstanceInvalidationClient, and
invalidation detected in one instance is broadcast to other instances by
remote procedure call.
Test: MultiInstanceInvalidationTest
Bug: 62334005
Bug: 80464228
Change-Id: I76033c5ac543ddaef735be06f828b7d7d607883a
M room/integration-tests/testapp/build.gradle
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
M room/integration-tests/testapp/src/main/AndroidManifest.xml
A room/integration-tests/testapp/src/main/aidl/androidx/room/integration/testapp/ISampleDatabaseService.aidl
A room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/SampleDatabaseService.java
M room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/CustomerDao.java
A room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/Product.java
A room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/ProductDao.java
M room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/SampleDatabase.java
M room/runtime/api/current.txt
M room/runtime/src/main/AndroidManifest.xml
A room/runtime/src/main/aidl/androidx/room/IMultiInstanceInvalidationCallback.aidl
A room/runtime/src/main/aidl/androidx/room/IMultiInstanceInvalidationService.aidl
M room/runtime/src/main/java/androidx/room/DatabaseConfiguration.java
M room/runtime/src/main/java/androidx/room/InvalidationTracker.java
A room/runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.java
A room/runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.java
M room/runtime/src/main/java/androidx/room/RoomDatabase.java
M room/testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
https://android-review.googlesource.com/720919
https://goto.google.com/android-sha1/41bbdfb46058e7ef3ea6aa21ac8d7a3c7642fa1d
Branch: androidx-master-dev
commit 41bbdfb46058e7ef3ea6aa21ac8d7a3c7642fa1d
Author: Yuichi Araki <yaraki@google.com>
Date: Wed May 23 17:38:58 2018
Multi-instance invalidation
Developers can now sync observers for InvalidationTracker and LiveData
between multiple RoomDatabase instances by
RoomDatabase.Builder.enableMultiInstanceInvalidation(). This can also be
used for database instances in other processes. All the instances have
to be using the same database file.
When multi-instance invalidation is turned on, all the tables are
observed by an instance of MultiInstanceInvalidationClient, and
invalidation detected in one instance is broadcast to other instances by
remote procedure call.
Test: MultiInstanceInvalidationTest
Bug: 62334005
Bug: 80464228
Change-Id: I76033c5ac543ddaef735be06f828b7d7d607883a
M room/integration-tests/testapp/build.gradle
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
M room/integration-tests/testapp/src/main/AndroidManifest.xml
A room/integration-tests/testapp/src/main/aidl/androidx/room/integration/testapp/ISampleDatabaseService.aidl
A room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/SampleDatabaseService.java
M room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/CustomerDao.java
A room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/Product.java
A room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/ProductDao.java
M room/integration-tests/testapp/src/main/java/androidx/room/integration/testapp/database/SampleDatabase.java
M room/runtime/api/current.txt
M room/runtime/src/main/AndroidManifest.xml
A room/runtime/src/main/aidl/androidx/room/IMultiInstanceInvalidationCallback.aidl
A room/runtime/src/main/aidl/androidx/room/IMultiInstanceInvalidationService.aidl
M room/runtime/src/main/java/androidx/room/DatabaseConfiguration.java
M room/runtime/src/main/java/androidx/room/InvalidationTracker.java
A room/runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.java
A room/runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.java
M room/runtime/src/main/java/androidx/room/RoomDatabase.java
M room/testing/src/main/java/androidx/room/testing/MigrationTestHelper.java
Description
Version used: 1.0.0-alpha1
Devices/Android versions reproduced on: Emulator