Skip to content

Conversation

@adam-hurwitz
Copy link

@adam-hurwitz adam-hurwitz commented Sep 21, 2020

Changes Summary

This resolves Issue #95.

  1. Disable Prepend loads that are not used in the sample. This will otherwise crash on the first load.
  2. Set default index for the first load in Append loads. This will otherwise crash on the first load.
  3. Remove RecyclerView flicker during loading state.

1. Disable Prepend loads

This error occurs on the first load since prepend is not enabled.

java.io.InvalidObjectException: Remote key and the prevKey should not be null

Full error log

2020-09-21 16:26:42.413 18648-18648/? E/codelabs.pagin: Unknown bits set in runtime_flags: 0x8000
2020-09-21 16:26:45.328 18648-18648/com.example.android.codelabs.paging E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.codelabs.paging, PID: 18648
java.io.InvalidObjectException: Remote key and the prevKey should not be null
at com.example.android.codelabs.paging.data.GithubRemoteMediator.load(GithubRemoteMediator.kt:56)
at androidx.paging.RemoteMediatorAccessor.doLoad(RemoteMediatorAccessor.kt:96)
at androidx.paging.RemoteMediatorAccessor$doLoad$1.invokeSuspend(Unknown Source:16)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:137)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:308)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:318)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:250)
at kotlinx.coroutines.ResumeOnCompletion.invoke(JobSupport.kt:1394)
at kotlinx.coroutines.JobSupport.notifyCompletion(JobSupport.kt:1529)
at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:323)
at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:240)
at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:903)
at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:860)
at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:825)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:111)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
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)

2. Set default index for the first load in Append loads.

This error occurs on the first load since the database has not yet been loaded with data.

java.io.InvalidObjectException: Remote key should not be null for APPEND

Full error log

2020-09-21 16:28:04.349 18779-18779/? E/codelabs.pagin: Unknown bits set in runtime_flags: 0x8000
2020-09-21 16:28:07.834 18779-18779/com.example.android.codelabs.paging E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.codelabs.paging, PID: 18779
java.io.InvalidObjectException: Remote key should not be null for APPEND
at com.example.android.codelabs.paging.data.GithubRemoteMediator.load(GithubRemoteMediator.kt:54)
at androidx.paging.RemoteMediatorAccessor.doLoad(RemoteMediatorAccessor.kt:96)
at androidx.paging.RemoteMediatorAccessor$load$$inlined$withLock$lambda$1.invokeSuspend(RemoteMediatorAccessor.kt:65)
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.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:184)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:308)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:318)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:250)
at kotlinx.coroutines.ResumeOnCompletion.invoke(JobSupport.kt:1394)
at kotlinx.coroutines.JobSupport.notifyCompletion(JobSupport.kt:1529)
at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:323)
at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:240)
at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:903)
at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:860)
at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:825)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:111)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
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)

3. Remove RecyclerView flicker during loading state.

The flicker was occurring every time new data was loaded.

florina-muntenescu and others added 30 commits April 14, 2018 14:36
Upgrading dependencies and moving lambda code to blocks
…-gradle-plugin

Use the stable version of Android Gradle Plugin instead of an alpha version
)

* Having the list backed by network only

* Showing an infinite scrolling list, from network, with Flow

* Using more KTX functionality and making the error an exception instead of string

* Adding ViewBinding

* Making the UI more material

* Removing searchRepos helper method

* Making the project compatible with Android Studio 3.6

* Step 0 - An infinite scrolling list, using Flow and LiveData

* Addressing review comments:
* Increasing build versions
* Formatting
* Added RequiresOptIn flag for coroutines and removing FlowPreview annotations

* [Bug fix] Don't increment the last requested page if the request failed

* Avoid duplicating data

* Libraries bump and removing Room annotations from Repo
florina-muntenescu and others added 2 commits July 23, 2020 20:02
• Disable Prepend loads which are not used.
• Set default index for the first load in Append loads. This will crash on the first load otherwise.
• Remove RecyclerView flicker during loading state
@adam-hurwitz adam-hurwitz changed the title fix: RemoteMediator fix: Issue #95 Sep 21, 2020
@adam-hurwitz adam-hurwitz changed the title fix: Issue #95 fix: Issue #95 with RemoteMediator First Load Sep 21, 2020
iamarjun added a commit to iamarjun/Food2Fork that referenced this pull request Sep 22, 2020
@johnjake
Copy link

johnjake commented Sep 28, 2020

in my case I remove the throw exception and replace them return MediatorResult.Success(endOfPaginationReached = true), on both APPEND and PREPEND

     val page = when (loadType) {
        LoadType.REFRESH -> {
            val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
            remoteKeys?.nextKey?.minus(1) ?: GITHUB_STARTING_PAGE_INDEX
        }
        LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
        LoadType.APPEND -> {
            val remoteKeys = getRemoteKeyForLastItem(state)
            if (remoteKeys?.nextKey == null) {
                return MediatorResult.Success(endOfPaginationReached = true)
            }
            remoteKeys.nextKey
        }
    }

@ghost
Copy link

ghost commented Oct 1, 2020

in my case I remove the throw exception and replace them return MediatorResult.Success(endOfPaginationReached = true), on both APPEND and PREPEND

     val page = when (loadType) {
        LoadType.REFRESH -> {
            val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
            remoteKeys?.nextKey?.minus(1) ?: GITHUB_STARTING_PAGE_INDEX
        }
        LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
        LoadType.APPEND -> {
            val remoteKeys = getRemoteKeyForLastItem(state)
            if (remoteKeys?.nextKey == null) {
                return MediatorResult.Success(endOfPaginationReached = true)
            }
            remoteKeys.nextKey
        }
    }

Yees, I did the same. Happy to see that someone did the same as I did. That solution worked also for me.

@doomtrooper
Copy link

doomtrooper commented Oct 15, 2020

What is the correct approach here? Any clue on why is it crashing?

@florina-muntenescu florina-muntenescu force-pushed the step13-19_network_and_database branch 2 times, most recently from fbf8ed3 to a42d4a1 Compare November 2, 2020 18:44
@florina-muntenescu florina-muntenescu force-pushed the step13-19_network_and_database branch from a42d4a1 to a7498e8 Compare November 18, 2020 17:26
@adam-hurwitz
Copy link
Author

@johnjake and @CelikAbdullah, this is a good solution as well!

@florina-muntenescu florina-muntenescu force-pushed the step13-19_network_and_database branch from a7498e8 to cf1c73b Compare January 6, 2021 10:55
@android-taoge
Copy link

LoadType.APPEND -> return MediatorResult.Success(endOfPaginationReached = true) , lead to load more trigger does not work at first launch.

here 's my code :

val page = when (loadType) {
            LoadType.REFRESH -> {
                val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
                remoteKeys?.nextKey?.minus(1) ?: GITHUB_STARTING_PAGE_INDEX
            }
            LoadType.PREPEND -> {
                val remoteKeys = getRemoteKeyForFirstItem(state)
                        ?: return MediatorResult.Success(endOfPaginationReached = false)
                remoteKeys.prevKey ?: return MediatorResult.Success(endOfPaginationReached = true)
                remoteKeys.prevKey
            }
            LoadType.APPEND -> {
                val remoteKeys = getRemoteKeyForLastItem(state)
                if (remoteKeys?.nextKey == null) {
                    return MediatorResult.Success(endOfPaginationReached = false)
                }
                remoteKeys.nextKey
            }

        }

@florina-muntenescu florina-muntenescu force-pushed the step13-19_network_and_database branch 5 times, most recently from 5f1732e to 6d26524 Compare March 23, 2021 10:36
@florina-muntenescu florina-muntenescu force-pushed the step13-19_network_and_database branch from 6d26524 to 39ffae8 Compare April 7, 2021 13:23
@florina-muntenescu florina-muntenescu force-pushed the step13-19_network_and_database branch from 39ffae8 to 1825ec5 Compare May 6, 2021 09:56
@tunjid tunjid force-pushed the step13-19_network_and_database branch from c9eebf1 to c5ea59c Compare June 30, 2021 14:03
@tunjid tunjid closed this Jul 30, 2021
@tunjid tunjid force-pushed the step13-19_network_and_database branch from a97db3c to 89de571 Compare July 30, 2021 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants