Fixed
Status Update
Comments
il...@google.com <il...@google.com>
cl...@google.com <cl...@google.com>
ap...@google.com <ap...@google.com> #2
Just to let you know that this issue present in the latest available release. I did just update to alpha09 and it breaks my code. My PagingSource if a Room backed source, but I have the same issue: the paging library failed to generate a separator for the first item.
It is still working with the alpha08.
fa...@hotmail.com <fa...@hotmail.com> #3
Project: platform/frameworks/support
Branch: androidx-master-dev
commit aa90cc2cb835209e12964d3afbc91e96b6d4e36b
Author: Dustin Lam <dustinlam@google.com>
Date: Tue Nov 24 11:34:08 2020
Add empty terminal insert for separators support with RemoteMediator
Re-applies a previous hack which inserted empty insert events to allow
separators to add terminal separators (header / footer), since
Separators may need to wait for a LoadStateUpdate event to mark terminal
load state from RemoteMediator.
Fixes: 172254056
Test: ./gradlew paging:paging-common:test
Change-Id: I5c5f2ac3860889909a30cd322a1e7b36eec1a9fd
M paging/common/src/main/kotlin/androidx/paging/MutableLoadStateCollection.kt
M paging/common/src/main/kotlin/androidx/paging/PageEvent.kt
M paging/common/src/main/kotlin/androidx/paging/PageFetcher.kt
M paging/common/src/main/kotlin/androidx/paging/Separators.kt
M paging/common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt
M paging/common/src/test/kotlin/androidx/paging/SeparatorsTest.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/room/CustomerDao.java
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/NetworkCustomerPagingSource.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RemoteMediator.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomAdapter.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomViewModel.kt
https://android-review.googlesource.com/1510174
Branch: androidx-master-dev
commit aa90cc2cb835209e12964d3afbc91e96b6d4e36b
Author: Dustin Lam <dustinlam@google.com>
Date: Tue Nov 24 11:34:08 2020
Add empty terminal insert for separators support with RemoteMediator
Re-applies a previous hack which inserted empty insert events to allow
separators to add terminal separators (header / footer), since
Separators may need to wait for a LoadStateUpdate event to mark terminal
load state from RemoteMediator.
Fixes: 172254056
Test: ./gradlew paging:paging-common:test
Change-Id: I5c5f2ac3860889909a30cd322a1e7b36eec1a9fd
M paging/common/src/main/kotlin/androidx/paging/MutableLoadStateCollection.kt
M paging/common/src/main/kotlin/androidx/paging/PageEvent.kt
M paging/common/src/main/kotlin/androidx/paging/PageFetcher.kt
M paging/common/src/main/kotlin/androidx/paging/Separators.kt
M paging/common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt
M paging/common/src/test/kotlin/androidx/paging/SeparatorsTest.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/room/CustomerDao.java
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/NetworkCustomerPagingSource.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RemoteMediator.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomAdapter.kt
M paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomViewModel.kt
Description
Version used: 2.1.0-alpha01
Devices/Android versions reproduced on: API 28 emulator, Chrome OS
MediatorLiveData.addSource doesn't manually check for null source argument (annotation is there, which is good)
It's possible to accidentally add a null (or not yet initialized) source.
The issue is buried until the MediatorLiveData is observed, making it hard to find the original issue.
Best solution would be a quick check of the variables and fast fail before processing. e.g. assertNotNull(source)
- Sample project attached
relevant code:
private val mediatorLiveData = MediatorLiveData<Int>().apply {
// Here is the mistake, (allowed at compile time).
addSource(dataSource) { value = (it ?: 0) + 1 }
}
private val dataSource = MutableLiveData<Int>()
// This triggers the exception
mediatorLiveData.observe(this, Observer { // process })
Error output without check: (unhelpful unless you know the internals of MediatorLiveData)
2019-01-18 10:58:39.891 6385-6385/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.example.mediatorlatecheck, PID: 6385
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observeForever(androidx.lifecycle.Observer)' on a null object reference
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:436)
at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:394)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:355)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:293)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:333)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:138)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:124)
at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:123)
at androidx.lifecycle.ReportFragment.onStart(ReportFragment.java:83)
at android.app.Fragment.performStart(Fragment.java:2548)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1334)
at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1576)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1637)
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3046)
at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:3003)
at android.app.FragmentController.dispatchStart(FragmentController.java:193)
at android.app.Activity.performStart(Activity.java:7165)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)