Fixed
Status Update
Comments
dr...@gmail.com <dr...@gmail.com> #2
For one of observables (single, maybe) we don't specify a subscvription thread so that developer can control where the action happens.
For flowables / observables; we always use the Room IO thread fo rthe actual query since we may repeat the work.
For LiveData, ti si always the Room IO Thread.
Until we can extend Room Query methods to receive non-query parameter (e.g. a Scheduler) we cannot do this.
At least room catches this instantly since it will crash w/ db access on main thread exception.
For flowables / observables; we always use the Room IO thread fo rthe actual query since we may repeat the work.
For LiveData, ti si always the Room IO Thread.
Until we can extend Room Query methods to receive non-query parameter (e.g. a Scheduler) we cannot do this.
At least room catches this instantly since it will crash w/ db access on main thread exception.
ki...@google.com <ki...@google.com>
no...@google.com <no...@google.com> #3
Hello Yigit, nice to meet you here! :)
Probably I should have described the problem more clearly.
I'm using Flowable, and hopefully it executes queries in background thread (at least, app does not crash with IllegalStateException, as with Single).
But nevertheless subscribing and disposing(!) does cause StrictMode violations. Stack trace examples:
D/StrictMode: StrictMode policy violation; ~duration=17 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1043)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:552)
at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)
at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction(FrameworkSQLiteDatabase.java:69)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:426)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:465)
at androidx.room.InvalidationTracker.addObserver(InvalidationTracker.java:249)
at androidx.room.RxRoom$1.subscribe(RxRoom.java:79)
at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:71)
at io.reactivex.Flowable.subscribe(Flowable.java:14479)
at io.reactivex.internal.operators.flowable.FlowableObserveOn.subscribeActual(FlowableObserveOn.java:56)
at io.reactivex.Flowable.subscribe(Flowable.java:14479)
at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe.subscribeActual(FlowableFlatMapMaybe.java:54)
at io.reactivex.Flowable.subscribe(Flowable.java:14479)
at io.reactivex.Flowable.subscribe(Flowable.java:14416)
at io.reactivex.Flowable.subscribe(Flowable.java:14306)
at gmk57.strictroom.MainActivity.onCreate(MainActivity.java:30)
StrictMode policy violation; ~duration=108 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1043)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:552)
at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)
at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction(FrameworkSQLiteDatabase.java:69)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:426)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:465)
at androidx.room.InvalidationTracker.removeObserver(InvalidationTracker.java:281)
at androidx.room.RxRoom$1$2.run(RxRoom.java:83)
at io.reactivex.disposables.ActionDisposable.onDisposed(ActionDisposable.java:30)
at io.reactivex.disposables.ActionDisposable.onDisposed(ActionDisposable.java:19)
at io.reactivex.disposables.ReferenceDisposable.dispose(ReferenceDisposable.java:43)
at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:72)
at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.cancel(FlowableCreate.java:301)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.cancel(FlowableObserveOn.java:154)
at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe$FlatMapMaybeSubscriber.cancel(FlowableFlatMapMaybe.java:158)
at io.reactivex.internal.subscriptions.SubscriptionHelper.cancel(SubscriptionHelper.java:189)
at io.reactivex.internal.subscribers.LambdaSubscriber.cancel(LambdaSubscriber.java:119)
at io.reactivex.internal.subscribers.LambdaSubscriber.dispose(LambdaSubscriber.java:104)
at gmk57.strictroom.MainActivity.onDestroy(MainActivity.java:37)
Probably I should have described the problem more clearly.
I'm using Flowable, and hopefully it executes queries in background thread (at least, app does not crash with IllegalStateException, as with Single).
But nevertheless subscribing and disposing(!) does cause StrictMode violations. Stack trace examples:
D/StrictMode: StrictMode policy violation; ~duration=17 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1043)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:552)
at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)
at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction(FrameworkSQLiteDatabase.java:69)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:426)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:465)
at androidx.room.InvalidationTracker.addObserver(InvalidationTracker.java:249)
at androidx.room.RxRoom$1.subscribe(RxRoom.java:79)
at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:71)
at io.reactivex.Flowable.subscribe(Flowable.java:14479)
at io.reactivex.internal.operators.flowable.FlowableObserveOn.subscribeActual(FlowableObserveOn.java:56)
at io.reactivex.Flowable.subscribe(Flowable.java:14479)
at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe.subscribeActual(FlowableFlatMapMaybe.java:54)
at io.reactivex.Flowable.subscribe(Flowable.java:14479)
at io.reactivex.Flowable.subscribe(Flowable.java:14416)
at io.reactivex.Flowable.subscribe(Flowable.java:14306)
at gmk57.strictroom.MainActivity.onCreate(MainActivity.java:30)
StrictMode policy violation; ~duration=108 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1043)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:552)
at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)
at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction(FrameworkSQLiteDatabase.java:69)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:426)
at androidx.room.InvalidationTracker.syncTriggers(InvalidationTracker.java:465)
at androidx.room.InvalidationTracker.removeObserver(InvalidationTracker.java:281)
at androidx.room.RxRoom$1$2.run(RxRoom.java:83)
at io.reactivex.disposables.ActionDisposable.onDisposed(ActionDisposable.java:30)
at io.reactivex.disposables.ActionDisposable.onDisposed(ActionDisposable.java:19)
at io.reactivex.disposables.ReferenceDisposable.dispose(ReferenceDisposable.java:43)
at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
at io.reactivex.internal.disposables.SequentialDisposable.dispose(SequentialDisposable.java:72)
at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.cancel(FlowableCreate.java:301)
at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.cancel(FlowableObserveOn.java:154)
at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe$FlatMapMaybeSubscriber.cancel(FlowableFlatMapMaybe.java:158)
at io.reactivex.internal.subscriptions.SubscriptionHelper.cancel(SubscriptionHelper.java:189)
at io.reactivex.internal.subscribers.LambdaSubscriber.cancel(LambdaSubscriber.java:119)
at io.reactivex.internal.subscribers.LambdaSubscriber.dispose(LambdaSubscriber.java:104)
at gmk57.strictroom.MainActivity.onDestroy(MainActivity.java:37)
si...@google.com <si...@google.com> #4
oh this is bad :/ we should fix it, thanks!
ap...@google.com <ap...@google.com> #5
Looks like it is broken for both add observer and remove observer since both are sync.
We need to investigate this better because these methods were not @WorkerThread before and we had to change them to fix some invalidation problems (see internal bug b/73592149 ).
Luckily this is not an issue for LiveData since it uses ComputableLiveData and always calls observe on a background thread.
We need to investigate this better because these methods were not @WorkerThread before and we had to change them to fix some invalidation problems (see internal bug
Luckily this is not an issue for LiveData since it uses ComputableLiveData and always calls observe on a background thread.
si...@google.com <si...@google.com>
an...@google.com <an...@google.com> #6
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 79deed62f2188a6ce2d21244dd28c3dc8ab6d0de
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Wed Oct 17 11:07:39 2018
Specify subscribeOn and unsubscribeOn scheduler in RxRoom.
Setting subscriber and unsubscriber schedulers prevents triggers being
synced in the main thread when subscribing or disposing a RxRoom
flowable / observable.
Moved beginTransaction() calls in InvalidationTracker outside the try,
finally with endTransaction() so that exceptions thrown by
beginTransaction() aren't aborted nor forgotten.
Bug: 117201279
Test: Manual test with sample app.
Change-Id: Iefb33dc63cf78e125a8805bd66a26ada365d8453
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/InvalidationTrackerTest.java
M room/runtime/src/main/java/androidx/room/InvalidationTracker.java
M room/rxjava2/src/main/java/androidx/room/RxRoom.java
M room/rxjava2/src/test/java/androidx/room/RxRoomTest.java
https://android-review.googlesource.com/792524
https://goto.google.com/android-sha1/79deed62f2188a6ce2d21244dd28c3dc8ab6d0de
Branch: androidx-master-dev
commit 79deed62f2188a6ce2d21244dd28c3dc8ab6d0de
Author: Daniel Santiago Rivera <danysantiago@google.com>
Date: Wed Oct 17 11:07:39 2018
Specify subscribeOn and unsubscribeOn scheduler in RxRoom.
Setting subscriber and unsubscriber schedulers prevents triggers being
synced in the main thread when subscribing or disposing a RxRoom
flowable / observable.
Moved beginTransaction() calls in InvalidationTracker outside the try,
finally with endTransaction() so that exceptions thrown by
beginTransaction() aren't aborted nor forgotten.
Bug: 117201279
Test: Manual test with sample app.
Change-Id: Iefb33dc63cf78e125a8805bd66a26ada365d8453
A room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/InvalidationTrackerTest.java
M room/runtime/src/main/java/androidx/room/InvalidationTracker.java
M room/rxjava2/src/main/java/androidx/room/RxRoom.java
M room/rxjava2/src/test/java/androidx/room/RxRoomTest.java
si...@google.com <si...@google.com> #8
Run
dr...@gmail.com <dr...@gmail.com> #9
Run
Description
When using
ResourcesCompat.getFont
to resolve a .ttf file in res/font, the returnedTypeface
instance always has a weight of 400 and a style ofNORMAL
.On all APIs < 29, style correctly resolves to
ITALIC
. On API 28, weight correctly resolves to 300.The font actually looks correct when displayed on an API 29 device, it just has the wrong values according to the
Typeface
instance.The issue is reproducible in this test class . Several tests fail on API 29 only due to this issue. I've also added a temporary
typefaceBug
test case that uses an ActivityScenario to demonstrate that the text actually appears correctly on API 29.