Result in PagingSource (paging library 3, Java)

37 Views Asked by At

Good afternoon

In the TMessagePagingSource class (extends from PagingSource<TMessageKey, TMessage>) I override the load() function:

public class TMessagePagingSource extends PagingSource<TMessageKey, TMessage> {

...

    @Nullable
    @Override
    public Object load(@NonNull LoadParams<TMessageKey> loadParams, @NonNull Continuation<? super LoadResult<TMessageKey, TMessage>> continuation) {

        TMessageKey pageKey = loadParams.getKey();

        if (pageKey == null) {
            pageKey = new TMessageKey(Long.MAX_VALUE, true, false);
        }

        int pageSize = loadParams.getLoadSize();

        mBackend.getTMessagesPage(pageKey, pageSize, this, continuation);

        return null;
    }

    public void toResult(TMessageResponse response, @NonNull Continuation<? super LoadResult<TMessageKey, TMessage>> continuation){

        LoadResult<TMessageKey, TMessage> result;
        try {
            result = new LoadResult.Page(
                    response.getMessages(),
                    response.getPrevPageKey(),
                    response.getNextPageKey()
            );
        } catch (Exception e) {
            result = new LoadResult.Error(e);
        }

        try {
            synchronized (continuation) {
                continuation.resumeWith(result);
            }
        } catch (Exception e) {}
    }
}

The mBackend.getTMessagesPage() function does not return the result immediately. It internally calls another function asynchronously, and that function, in turn, asynchronously calls another one. As a result, one of the asynchronous nested functions returns the result (pagingSource.toResult(response, continuation)):

    public void getTMessagesPage(TMessageKey pageKey, int pageSize, TMessagePagingSource pagingSource, @NonNull Continuation<? super PagingSource.LoadResult<TMessageKey, TMessage>> continuation) {

        List<TMessage> tMessages = new ArrayList<TMessage>();
        ...
        getTMessagesPageStep(281126480l, 0, pageKey, limit, tMessages, pagingSource, continuation);
    }

    public void getTMessagesPageStep(long chatID, long fromMessageId, TMessageKey pageKey, int limit, List<TMessage> tMessages, TMessagePagingSource pagingSource, @NonNull Continuation<? super PagingSource.LoadResult<TMessageKey, TMessage>> continuation) {
        ...
        client.send(new TdApi.GetChatHistory(chatID, fromMessageId, offset, lLimit, false), new Client.ResultHandler() {

            @Override
            public void onResult(TdApi.Object object) {
                ...
                if(msgCount > 0){
                    getTMessagesPageStep(chatID, lastMessageId, pageKey, limit, tMessages, pagingSource, continuation);
                } else{
                    getTMessagesPageStepResult(chatID, pageKey, limit, tMessages, pagingSource, continuation);
                }
            }
        });
    }

    public void getTMessagesPageStepResult(long chatID, TMessageKey pageKey, int limit, List<TMessage> tMessages, TMessagePagingSource pagingSource, @NonNull Continuation<? super PagingSource.LoadResult<TMessageKey, TMessage>> continuation) {
        ...
        TMessageResponse response = new TMessageResponse(tMessages, nextPageKey, prevPageKey);
        pagingSource.toResult(response, continuation); // Returns the result
    }

Result: after the first execution of continuation.resumeWith(result), the program continues to run, but returns an error (maybe because I'm returning null to the load() function?):

Job ScopeCoroutine{Completing}@a273a68 is already complete or completing, but is being completed with CompletedExceptionally[java.lang.IllegalStateException: This mutex is not locked]

After the second call to continuation.resumeWith(result), the program closes itself without printing an error.

Android API 21

I think I'm using Continuation incorrectly, but I haven't found how to do it in Java.

Expected that with the help of Continuation I would be able to correctly pass LoadResult<TMessageKey, TMessage> the result of the load() function without causing errors. Perhaps this can be done without using Continuation

Please tell me I have little experience in writing Android applications

0

There are 0 best solutions below