public abstract class

RemoteWorkManager

extends java.lang.Object

 java.lang.Object

↳androidx.work.multiprocess.RemoteWorkManager

Subclasses:

RemoteWorkManagerClient

Gradle dependencies

compile group: 'androidx.work', name: 'work-runtime', version: '2.8.0-alpha02'

  • groupId: androidx.work
  • artifactId: work-runtime
  • version: 2.8.0-alpha02

Artifact androidx.work:work-runtime:2.8.0-alpha02 it located at Google repository (https://maven.google.com/)

Overview

A subset of WorkManager APIs that are available for apps that use multiple processes.

Summary

Constructors
protectedRemoteWorkManager()

Methods
public abstract RemoteWorkContinuationbeginUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, java.util.List<OneTimeWorkRequest> work)

This method allows you to begin unique chains of work for situations where you only want one chain with a given name to be active at a time.

public final RemoteWorkContinuationbeginUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, OneTimeWorkRequest work)

This method allows you to begin unique chains of work for situations where you only want one chain with a given name to be active at a time.

public abstract RemoteWorkContinuationbeginWith(java.util.List<OneTimeWorkRequest> work)

Begins a chain with one or more OneTimeWorkRequests, which can be enqueued together in the future using RemoteWorkContinuation.enqueue().

public final RemoteWorkContinuationbeginWith(OneTimeWorkRequest work)

Begins a chain with one or more OneTimeWorkRequests, which can be enqueued together in the future using RemoteWorkContinuation.enqueue().

public abstract <any>cancelAllWork()

Cancels all unfinished work.

public abstract <any>cancelAllWorkByTag(java.lang.String tag)

Cancels all unfinished work with the given tag.

public abstract <any>cancelUniqueWork(java.lang.String uniqueWorkName)

Cancels all unfinished work in the work chain with the given name.

public abstract <any>cancelWorkById(java.util.UUID id)

Cancels work with the given id if it isn't finished.

public abstract <any>enqueue(java.util.List<WorkRequest> requests)

Enqueues one or more items for background processing.

public abstract <any>enqueue(WorkContinuation continuation)

Enqueues the instance of WorkContinuation for background processing.

public abstract <any>enqueue(WorkRequest request)

Enqueues one item for background processing.

public abstract <any>enqueueUniquePeriodicWork(java.lang.String uniqueWorkName, ExistingPeriodicWorkPolicy existingPeriodicWorkPolicy, PeriodicWorkRequest periodicWork)

This method allows you to enqueue a uniquely-named PeriodicWorkRequest, where only one PeriodicWorkRequest of a particular name can be active at a time.

public abstract <any>enqueueUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, java.util.List<OneTimeWorkRequest> work)

This method allows you to enqueue work requests to a uniquely-named RemoteWorkContinuation, where only one continuation of a particular name can be active at a time.

public final <any>enqueueUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, OneTimeWorkRequest work)

This method allows you to enqueue work requests to a uniquely-named RemoteWorkContinuation, where only one continuation of a particular name can be active at a time.

public static RemoteWorkManagergetInstance(Context context)

Gets the instance of RemoteWorkManager which provides a subset of WorkManager APIs that are safe to use for apps that use multiple processes.

public abstract <any>getWorkInfos(WorkQuery workQuery)

Gets the of the java.util.List of WorkInfo for all work referenced by the WorkQuery specification.

public abstract <any>setForegroundAsync(java.lang.String id, ForegroundInfo foregroundInfo)

Delegates the call to ListenableWorker.setForegroundAsync(ForegroundInfo) to the designated process.

public abstract <any>setProgress(java.util.UUID id, Data data)

Updates progress information for a ListenableWorker.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

protected RemoteWorkManager()

Methods

public abstract <any> enqueue(WorkRequest request)

Enqueues one item for background processing.

Parameters:

request: The WorkRequest to enqueue

Returns:

A that can be used to determine when the enqueue has completed

public abstract <any> enqueue(java.util.List<WorkRequest> requests)

Enqueues one or more items for background processing.

Parameters:

requests: One or more WorkRequest to enqueue

Returns:

A that can be used to determine when the enqueue has completed

public final <any> enqueueUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, OneTimeWorkRequest work)

This method allows you to enqueue work requests to a uniquely-named RemoteWorkContinuation, where only one continuation of a particular name can be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

The uniqueWorkName uniquely identifies this RemoteWorkContinuation.

Parameters:

uniqueWorkName: A unique name which for this operation
existingWorkPolicy: An ExistingWorkPolicy; see below for more information
work: The OneTimeWorkRequests to enqueue. REPLACE ensures that if there is pending work labelled with uniqueWorkName, it will be cancelled and the new work will run. KEEP will run the new OneTimeWorkRequests only if there is no pending work labelled with uniqueWorkName. APPEND will append the OneTimeWorkRequests as leaf nodes labelled with uniqueWorkName.

Returns:

A that can be used to determine when the enqueue has completed

public abstract <any> enqueueUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, java.util.List<OneTimeWorkRequest> work)

This method allows you to enqueue work requests to a uniquely-named RemoteWorkContinuation, where only one continuation of a particular name can be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

The uniqueWorkName uniquely identifies this RemoteWorkContinuation.

Parameters:

uniqueWorkName: A unique name which for this operation
existingWorkPolicy: An ExistingWorkPolicy
work: OneTimeWorkRequests to enqueue. REPLACE ensures that if there is pending work labelled with uniqueWorkName, it will be cancelled and the new work will run. KEEP will run the new OneTimeWorkRequests only if there is no pending work labelled with uniqueWorkName. APPEND will append the OneTimeWorkRequests as leaf nodes labelled with uniqueWorkName.

Returns:

A that can be used to determine when the enqueue has completed

public abstract <any> enqueueUniquePeriodicWork(java.lang.String uniqueWorkName, ExistingPeriodicWorkPolicy existingPeriodicWorkPolicy, PeriodicWorkRequest periodicWork)

This method allows you to enqueue a uniquely-named PeriodicWorkRequest, where only one PeriodicWorkRequest of a particular name can be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

The uniqueWorkName uniquely identifies this PeriodicWorkRequest.

Parameters:

uniqueWorkName: A unique name which for this operation
existingPeriodicWorkPolicy: An ExistingPeriodicWorkPolicy
periodicWork: A PeriodicWorkRequest to enqueue. REPLACE ensures that if there is pending work labelled with uniqueWorkName, it will be cancelled and the new work will run. KEEP will run the new PeriodicWorkRequest only if there is no pending work labelled with uniqueWorkName.

Returns:

An that can be used to determine when the enqueue has completed

public final RemoteWorkContinuation beginWith(OneTimeWorkRequest work)

Begins a chain with one or more OneTimeWorkRequests, which can be enqueued together in the future using RemoteWorkContinuation.enqueue().

If any work in the chain fails or is cancelled, all of its dependent work inherits that state and will never run.

Parameters:

work: One or more OneTimeWorkRequest to start a chain of work

Returns:

A RemoteWorkContinuation that allows for further chaining of dependent OneTimeWorkRequest

public abstract RemoteWorkContinuation beginWith(java.util.List<OneTimeWorkRequest> work)

Begins a chain with one or more OneTimeWorkRequests, which can be enqueued together in the future using RemoteWorkContinuation.enqueue().

If any work in the chain fails or is cancelled, all of its dependent work inherits that state and will never run.

Parameters:

work: One or more OneTimeWorkRequest to start a chain of work

Returns:

A RemoteWorkContinuation that allows for further chaining of dependent OneTimeWorkRequest

public final RemoteWorkContinuation beginUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, OneTimeWorkRequest work)

This method allows you to begin unique chains of work for situations where you only want one chain with a given name to be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

The uniqueWorkName uniquely identifies this set of work.

If this method determines that new work should be enqueued and run, all records of previous work with uniqueWorkName will be pruned. If this method determines that new work should NOT be run, then the entire chain will be considered a no-op.

If any work in the chain fails or is cancelled, all of its dependent work inherits that state and will never run. This is particularly important if you are using APPEND as your ExistingWorkPolicy.

Parameters:

uniqueWorkName: A unique name which for this chain of work
existingWorkPolicy: An ExistingWorkPolicy
work: The OneTimeWorkRequest to enqueue. REPLACE ensures that if there is pending work labelled with uniqueWorkName, it will be cancelled and the new work will run. KEEP will run the new sequence of work only if there is no pending work labelled with uniqueWorkName. APPEND will create a new sequence of work if there is no existing work with uniqueWorkName; otherwise, work will be added as a child of all leaf nodes labelled with uniqueWorkName.

Returns:

A RemoteWorkContinuation that allows further chaining

public abstract RemoteWorkContinuation beginUniqueWork(java.lang.String uniqueWorkName, ExistingWorkPolicy existingWorkPolicy, java.util.List<OneTimeWorkRequest> work)

This method allows you to begin unique chains of work for situations where you only want one chain with a given name to be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

The uniqueWorkName uniquely identifies this set of work.

If this method determines that new work should be enqueued and run, all records of previous work with uniqueWorkName will be pruned. If this method determines that new work should NOT be run, then the entire chain will be considered a no-op.

If any work in the chain fails or is cancelled, all of its dependent work inherits that state and will never run. This is particularly important if you are using APPEND as your ExistingWorkPolicy.

Parameters:

uniqueWorkName: A unique name which for this chain of work
existingWorkPolicy: An ExistingWorkPolicy; see below for more information
work: One or more OneTimeWorkRequest to enqueue. REPLACE ensures that if there is pending work labelled with uniqueWorkName, it will be cancelled and the new work will run. KEEP will run the new sequence of work only if there is no pending work labelled with uniqueWorkName. APPEND will create a new sequence of work if there is no existing work with uniqueWorkName; otherwise, work will be added as a child of all leaf nodes labelled with uniqueWorkName.

Returns:

A RemoteWorkContinuation that allows further chaining

public abstract <any> enqueue(WorkContinuation continuation)

Enqueues the instance of WorkContinuation for background processing.

Returns:

A that can be used to determine when the enqueue has completed

public abstract <any> cancelWorkById(java.util.UUID id)

Cancels work with the given id if it isn't finished. Note that cancellation is a best-effort policy and work that is already executing may continue to run. Upon cancellation, ListenableWorker.onStopped() will be invoked for any affected workers.

Parameters:

id: The id of the work

Returns:

A that can be used to determine when the cancelWorkById has completed

public abstract <any> cancelAllWorkByTag(java.lang.String tag)

Cancels all unfinished work with the given tag. Note that cancellation is a best-effort policy and work that is already executing may continue to run. Upon cancellation, ListenableWorker.onStopped() will be invoked for any affected workers.

Parameters:

tag: The tag used to identify the work

Returns:

An that can be used to determine when the cancelAllWorkByTag has completed

public abstract <any> cancelUniqueWork(java.lang.String uniqueWorkName)

Cancels all unfinished work in the work chain with the given name. Note that cancellation is a best-effort policy and work that is already executing may continue to run. Upon cancellation, ListenableWorker.onStopped() will be invoked for any affected workers.

Parameters:

uniqueWorkName: The unique name used to identify the chain of work

Returns:

A that can be used to determine when the cancelUniqueWork has completed

public abstract <any> cancelAllWork()

Cancels all unfinished work. Use this method with extreme caution! By invoking it, you will potentially affect other modules or libraries in your codebase. It is strongly recommended that you use one of the other cancellation methods at your disposal.

Upon cancellation, ListenableWorker.onStopped() will be invoked for any affected workers.

Returns:

A that can be used to determine when the cancelAllWork has completed

public abstract <any> getWorkInfos(WorkQuery workQuery)

Gets the of the java.util.List of WorkInfo for all work referenced by the WorkQuery specification.

Parameters:

workQuery: The work query specification

Returns:

A of the java.util.List of WorkInfo for work referenced by this WorkQuery.

public abstract <any> setProgress(java.util.UUID id, Data data)

Updates progress information for a ListenableWorker.

Parameters:

id: The WorkRequest id
data: The progress Data

Returns:

A that can be used to determine when the setProgress has completed.

public abstract <any> setForegroundAsync(java.lang.String id, ForegroundInfo foregroundInfo)

Delegates the call to ListenableWorker.setForegroundAsync(ForegroundInfo) to the designated process.

Parameters:

id: The WorkRequest id
foregroundInfo: THe ForegroundInfo instance

Returns:

A that can be used to determine when the setForeground has completed.

public static RemoteWorkManager getInstance(Context context)

Gets the instance of RemoteWorkManager which provides a subset of WorkManager APIs that are safe to use for apps that use multiple processes.

Parameters:

context: The application context.

Returns:

The instance of RemoteWorkManager.

Source

/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.work.multiprocess;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.work.Data;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.ExistingWorkPolicy;
import androidx.work.ForegroundInfo;
import androidx.work.ListenableWorker;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkContinuation;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import androidx.work.WorkQuery;
import androidx.work.WorkRequest;
import androidx.work.impl.WorkManagerImpl;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * A subset of {@link androidx.work.WorkManager} APIs that are available for apps that use
 * multiple processes.
 */
public abstract class RemoteWorkManager {
    /**
     * @hide
     */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    protected RemoteWorkManager() {
        // Does nothing
    }

    /**
     * Enqueues one item for background processing.
     *
     * @param request The {@link WorkRequest} to enqueue
     * @return A {@link ListenableFuture} that can be used to determine when the enqueue has
     * completed
     */
    @NonNull
    public abstract ListenableFuture<Void> enqueue(@NonNull WorkRequest request);

    /**
     * Enqueues one or more items for background processing.
     *
     * @param requests One or more {@link WorkRequest} to enqueue
     * @return A {@link ListenableFuture} that can be used to determine when the enqueue has
     * completed
     */
    @NonNull
    public abstract ListenableFuture<Void> enqueue(@NonNull List<WorkRequest> requests);

    /**
     * This method allows you to enqueue {@code work} requests to a uniquely-named
     * {@link RemoteWorkContinuation}, where only one continuation of a particular name can be
     * active at a time. For example, you may only want one sync operation to be active. If there
     * is one pending, you can choose to let it run or replace it with your new work.
     * <p>
     * The {@code uniqueWorkName} uniquely identifies this {@link RemoteWorkContinuation}.
     *
     * @param uniqueWorkName A unique name which for this operation
     * @param existingWorkPolicy An {@link ExistingWorkPolicy}; see below for more information
     * @param work The {@link OneTimeWorkRequest}s to enqueue. {@code REPLACE} ensures that if there
     *             is pending work labelled with {@code uniqueWorkName}, it will be cancelled and
     *             the new work will run. {@code KEEP} will run the new OneTimeWorkRequests only if
     *             there is no pending work labelled with {@code uniqueWorkName}.  {@code APPEND}
     *             will append the OneTimeWorkRequests as leaf nodes labelled with
     *             {@code uniqueWorkName}.
     * @return A {@link ListenableFuture} that can be used to determine when the enqueue has
     * completed
     */
    @NonNull
    public final ListenableFuture<Void> enqueueUniqueWork(
            @NonNull String uniqueWorkName,
            @NonNull ExistingWorkPolicy existingWorkPolicy,
            @NonNull OneTimeWorkRequest work) {
        return enqueueUniqueWork(
                uniqueWorkName,
                existingWorkPolicy,
                Collections.singletonList(work));
    }

    /**
     * This method allows you to enqueue {@code work} requests to a uniquely-named
     * {@link RemoteWorkContinuation}, where only one continuation of a particular name can be
     * active at a time. For example, you may only want one sync operation to be active. If there
     * is one pending, you can choose to let it run or replace it with your new work.
     * <p>
     * The {@code uniqueWorkName} uniquely identifies this {@link RemoteWorkContinuation}.
     *
     * @param uniqueWorkName A unique name which for this operation
     * @param existingWorkPolicy An {@link ExistingWorkPolicy}
     * @param work {@link OneTimeWorkRequest}s to enqueue. {@code REPLACE} ensures
     *                     that if there is pending work labelled with {@code uniqueWorkName}, it
     *                     will be cancelled and the new work will run. {@code KEEP} will run the
     *                     new OneTimeWorkRequests only if there is no pending work labelled with
     *                     {@code uniqueWorkName}. {@code APPEND} will append the
     *                     OneTimeWorkRequests as leaf nodes labelled with {@code uniqueWorkName}.
     * @return A {@link ListenableFuture} that can be used to determine when the enqueue has
     * completed
     */
    @NonNull
    public abstract ListenableFuture<Void> enqueueUniqueWork(
            @NonNull String uniqueWorkName,
            @NonNull ExistingWorkPolicy existingWorkPolicy,
            @NonNull List<OneTimeWorkRequest> work);

    /**
     * This method allows you to enqueue a uniquely-named {@link PeriodicWorkRequest}, where only
     * one PeriodicWorkRequest of a particular name can be active at a time.  For example, you may
     * only want one sync operation to be active.  If there is one pending, you can choose to let it
     * run or replace it with your new work.
     * <p>
     * The {@code uniqueWorkName} uniquely identifies this PeriodicWorkRequest.
     *
     * @param uniqueWorkName A unique name which for this operation
     * @param existingPeriodicWorkPolicy An {@link ExistingPeriodicWorkPolicy}
     * @param periodicWork A {@link PeriodicWorkRequest} to enqueue. {@code REPLACE} ensures that if
     *                     there is pending work labelled with {@code uniqueWorkName}, it will be
     *                     cancelled and the new work will run. {@code KEEP} will run the new
     *                     PeriodicWorkRequest only if there is no pending work labelled with
     *                     {@code uniqueWorkName}.
     * @return An {@link ListenableFuture} that can be used to determine when the enqueue has
     * completed
     */
    @NonNull
    public abstract ListenableFuture<Void> enqueueUniquePeriodicWork(
            @NonNull String uniqueWorkName,
            @NonNull ExistingPeriodicWorkPolicy existingPeriodicWorkPolicy,
            @NonNull PeriodicWorkRequest periodicWork);

    /**
     * Begins a chain with one or more {@link OneTimeWorkRequest}s, which can be enqueued together
     * in the future using {@link RemoteWorkContinuation#enqueue()}.
     * <p>
     * If any work in the chain fails or is cancelled, all of its dependent work inherits that state
     * and will never run.
     *
     * @param work One or more {@link OneTimeWorkRequest} to start a chain of work
     * @return A {@link RemoteWorkContinuation} that allows for further chaining of dependent
     * {@link OneTimeWorkRequest}
     */
    @NonNull
    public final RemoteWorkContinuation beginWith(@NonNull OneTimeWorkRequest work) {
        return beginWith(Collections.singletonList(work));
    }

    /**
     * Begins a chain with one or more {@link OneTimeWorkRequest}s, which can be enqueued together
     * in the future using {@link RemoteWorkContinuation#enqueue()}.
     * <p>
     * If any work in the chain fails or is cancelled, all of its dependent work inherits that state
     * and will never run.
     *
     * @param work One or more {@link OneTimeWorkRequest} to start a chain of work
     * @return A {@link RemoteWorkContinuation} that allows for further chaining of dependent
     * {@link OneTimeWorkRequest}
     */
    @NonNull
    public abstract RemoteWorkContinuation beginWith(@NonNull List<OneTimeWorkRequest> work);

    /**
     * This method allows you to begin unique chains of work for situations where you only want one
     * chain with a given name to be active at a time.  For example, you may only want one sync
     * operation to be active.  If there is one pending, you can choose to let it run or replace it
     * with your new work.
     * <p>
     * The {@code uniqueWorkName} uniquely identifies this set of work.
     * <p>
     * If this method determines that new work should be enqueued and run, all records of previous
     * work with {@code uniqueWorkName} will be pruned.  If this method determines that new work
     * should NOT be run, then the entire chain will be considered a no-op.
     * <p>
     * If any work in the chain fails or is cancelled, all of its dependent work inherits that state
     * and will never run.  This is particularly important if you are using {@code APPEND} as your
     * {@link ExistingWorkPolicy}.
     *
     * @param uniqueWorkName A unique name which for this chain of work
     * @param existingWorkPolicy An {@link ExistingWorkPolicy}
     * @param work The {@link OneTimeWorkRequest} to enqueue. {@code REPLACE} ensures that if there
     *             is pending work labelled with {@code uniqueWorkName}, it will be cancelled and
     *             the new work will run. {@code KEEP} will run the new sequence of work only if
     *             there is no pending work labelled with {@code uniqueWorkName}.  {@code APPEND}
     *             will create a new sequence of work if there is no existing work with
     *             {@code uniqueWorkName}; otherwise, {@code work} will be added as a child of all
     *             leaf nodes labelled with {@code uniqueWorkName}.
     * @return A {@link RemoteWorkContinuation} that allows further chaining
     */
    @NonNull
    public final RemoteWorkContinuation beginUniqueWork(
            @NonNull String uniqueWorkName,
            @NonNull ExistingWorkPolicy existingWorkPolicy,
            @NonNull OneTimeWorkRequest work) {
        return beginUniqueWork(uniqueWorkName, existingWorkPolicy, Collections.singletonList(work));
    }

    /**
     * This method allows you to begin unique chains of work for situations where you only want one
     * chain with a given name to be active at a time.  For example, you may only want one sync
     * operation to be active.  If there is one pending, you can choose to let it run or replace it
     * with your new work.
     * <p>
     * The {@code uniqueWorkName} uniquely identifies this set of work.
     * <p>
     * If this method determines that new work should be enqueued and run, all records of previous
     * work with {@code uniqueWorkName} will be pruned.  If this method determines that new work
     * should NOT be run, then the entire chain will be considered a no-op.
     * <p>
     * If any work in the chain fails or is cancelled, all of its dependent work inherits that state
     * and will never run.  This is particularly important if you are using {@code APPEND} as your
     * {@link ExistingWorkPolicy}.
     *
     * @param uniqueWorkName A unique name which for this chain of work
     * @param existingWorkPolicy An {@link ExistingWorkPolicy}; see below for more information
     * @param work One or more {@link OneTimeWorkRequest} to enqueue. {@code REPLACE} ensures that
     *             if there is pending work labelled with {@code uniqueWorkName}, it will be
     *             cancelled and the new work will run. {@code KEEP} will run the new sequence of
     *             work only if there is no pending work labelled with {@code uniqueWorkName}.
     *             {@code APPEND} will create a new sequence of work if there is no
     *             existing work with {@code uniqueWorkName}; otherwise, {@code work} will be added
     *             as a child of all leaf nodes labelled with {@code uniqueWorkName}.
     * @return A {@link RemoteWorkContinuation} that allows further chaining
     */
    @NonNull
    public abstract RemoteWorkContinuation beginUniqueWork(
            @NonNull String uniqueWorkName,
            @NonNull ExistingWorkPolicy existingWorkPolicy,
            @NonNull List<OneTimeWorkRequest> work);

    /**
     * Enqueues the instance of {@link WorkContinuation} for background processing.
     *
     * @return A {@link ListenableFuture} that can be used to determine when the enqueue has
     * completed
     * @hide
     */
    @NonNull
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public abstract ListenableFuture<Void> enqueue(@NonNull WorkContinuation continuation);

    /**
     * Cancels work with the given id if it isn't finished.  Note that cancellation is a best-effort
     * policy and work that is already executing may continue to run.  Upon cancellation,
     * {@link ListenableWorker#onStopped()} will be invoked for any affected workers.
     *
     * @param id The id of the work
     * @return A {@link ListenableFuture} that can be used to determine when the cancelWorkById has
     * completed
     */
    @NonNull
    public abstract ListenableFuture<Void> cancelWorkById(@NonNull UUID id);

    /**
     * Cancels all unfinished work with the given tag.  Note that cancellation is a best-effort
     * policy and work that is already executing may continue to run.  Upon cancellation,
     * {@link ListenableWorker#onStopped()} will be invoked for any affected workers.
     *
     * @param tag The tag used to identify the work
     * @return An {@link ListenableFuture} that can be used to determine when the
     * cancelAllWorkByTag has completed
     */
    @NonNull
    public abstract ListenableFuture<Void> cancelAllWorkByTag(@NonNull String tag);

    /**
     * Cancels all unfinished work in the work chain with the given name.  Note that cancellation is
     * a best-effort policy and work that is already executing may continue to run.  Upon
     * cancellation, {@link ListenableWorker#onStopped()} will be invoked for any affected workers.
     *
     * @param uniqueWorkName The unique name used to identify the chain of work
     * @return A {@link ListenableFuture} that can be used to determine when the cancelUniqueWork
     * has completed
     */
    @NonNull
    public abstract ListenableFuture<Void> cancelUniqueWork(@NonNull String uniqueWorkName);

    /**
     * Cancels all unfinished work.  <b>Use this method with extreme caution!</b>  By invoking it,
     * you will potentially affect other modules or libraries in your codebase.  It is strongly
     * recommended that you use one of the other cancellation methods at your disposal.
     * <p>
     * Upon cancellation, {@link ListenableWorker#onStopped()} will be invoked for any affected
     * workers.
     *
     * @return A {@link ListenableFuture} that can be used to determine when the cancelAllWork has
     * completed
     */
    @NonNull
    public abstract ListenableFuture<Void> cancelAllWork();

    /**
     * Gets the {@link ListenableFuture} of the {@link List} of {@link WorkInfo} for all work
     * referenced by the {@link WorkQuery} specification.
     *
     * @param workQuery The work query specification
     * @return A {@link ListenableFuture} of the {@link List} of {@link WorkInfo} for work
     * referenced by this {@link WorkQuery}.
     */
    @NonNull
    public abstract ListenableFuture<List<WorkInfo>> getWorkInfos(@NonNull WorkQuery workQuery);

    /**
     * Updates progress information for a {@link ListenableWorker}.
     *
     * @param id   The {@link WorkRequest} id
     * @param data The progress {@link Data}
     * @return A {@link ListenableFuture} that can be used to determine when the setProgress
     * has completed.
     * @hide
     */
    @NonNull
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public abstract ListenableFuture<Void> setProgress(@NonNull UUID id, @NonNull Data data);

    /**
     * Delegates the call to {@link ListenableWorker#setForegroundAsync(ForegroundInfo)} to the
     * designated process.
     *
     * @param id             The {@link WorkRequest} id
     * @param foregroundInfo THe {@link ForegroundInfo} instance
     * @return A {@link ListenableFuture} that can be used to determine when the setForeground
     * has completed.
     * @hide
     */
    @NonNull
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public abstract ListenableFuture<Void> setForegroundAsync(
            @NonNull String id,
            @NonNull ForegroundInfo foregroundInfo);

    /**
     * Gets the instance of {@link RemoteWorkManager} which provides a subset of
     * {@link WorkManager} APIs that are safe to use for apps that use multiple processes.
     *
     * @param context The application context.
     * @return The instance of {@link RemoteWorkManager}.
     */
    @NonNull
    public static RemoteWorkManager getInstance(@NonNull Context context) {
        WorkManagerImpl workManager = WorkManagerImpl.getInstance(context);
        RemoteWorkManager remoteWorkManager = workManager.getRemoteWorkManager();
        if (remoteWorkManager == null) {
            // Should never really happen.
            throw new IllegalStateException("Unable to initialize RemoteWorkManager");
        }
        return remoteWorkManager;
    }
}