1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package androidx.work; 17 18 import androidx.annotation.RestrictTo; 19 import androidx.lifecycle.LifecycleOwner; 20 import androidx.lifecycle.LiveData; 21 import androidx.lifecycle.Observer; 22 23 import com.google.common.util.concurrent.ListenableFuture; 24 25 import org.jspecify.annotations.NonNull; 26 27 import java.util.Collections; 28 import java.util.List; 29 30 /** 31 * A class that allows you to chain together {@link OneTimeWorkRequest}s. WorkContinuations allow 32 * the user to create arbitrary acyclic graphs of work dependencies. You can add dependent work to 33 * a WorkContinuation by invoking {@link #then(OneTimeWorkRequest)} or its variants. This returns a 34 * new WorkContinuation. 35 * <p> 36 * To construct more complex graphs, {@link WorkContinuation#combine(List)} or its 37 * variants can be used to return a WorkContinuation with the input WorkContinuations as 38 * prerequisites. To create a graph like this: 39 * 40 * <pre> 41 * A C 42 * | | 43 * B D 44 * | | 45 * +-------+ 46 * | 47 * E </pre> 48 * 49 * you would write the following: 50 * 51 * <pre class="prettyprint"> 52 * WorkContinuation left = workManager.beginWith(A).then(B); 53 * WorkContinuation right = workManager.beginWith(C).then(D); 54 * WorkContinuation final = WorkContinuation.combine(Arrays.asList(left, right)).then(E); 55 * final.enqueue(); 56 * </pre> 57 * 58 * Not that enqueuing a WorkContinuation enqueues all previously-unenqueued prerequisites. You must 59 * call {@link #enqueue()} to inform WorkManager to actually enqueue the work graph. As usual, 60 * enqueues are asynchronous - you can observe or block on the returned {@link Operation} if you 61 * need to be informed about its completion. 62 * <p> 63 * Because of the fluent nature of this class, its existence should be invisible in most cases. 64 */ 65 66 public abstract class WorkContinuation { 67 68 /** 69 * Adds new {@link OneTimeWorkRequest} items that depend on the successful completion of 70 * all previously added {@link OneTimeWorkRequest}s. 71 * 72 * @param work One or more {@link OneTimeWorkRequest}s to add as dependents 73 * @return A {@link WorkContinuation} that allows for further chaining of dependent 74 * {@link OneTimeWorkRequest}s 75 */ then(@onNull OneTimeWorkRequest work)76 public final @NonNull WorkContinuation then(@NonNull OneTimeWorkRequest work) { 77 return then(Collections.singletonList(work)); 78 } 79 80 /** 81 * Adds new {@link OneTimeWorkRequest} items that depend on the successful completion 82 * of all previously added {@link OneTimeWorkRequest}s. 83 * 84 * @param work One or more {@link OneTimeWorkRequest} to add as dependents 85 * @return A {@link WorkContinuation} that allows for further chaining of dependent 86 * {@link OneTimeWorkRequest}s 87 */ then(@onNull List<OneTimeWorkRequest> work)88 public abstract @NonNull WorkContinuation then(@NonNull List<OneTimeWorkRequest> work); 89 90 /** 91 * Returns a {@link LiveData} list of {@link WorkInfo}s that provide information about the 92 * status of each {@link OneTimeWorkRequest} in this {@link WorkContinuation}, as well as their 93 * prerequisites. If the state or outputs of any of the work changes, any attached 94 * {@link Observer}s will trigger. 95 * 96 * @return A {@link LiveData} containing a list of {@link WorkInfo}s; you must use 97 * {@link LiveData#observe(LifecycleOwner, Observer)} to receive updates 98 */ getWorkInfosLiveData()99 public abstract @NonNull LiveData<List<WorkInfo>> getWorkInfosLiveData(); 100 101 /** 102 * Returns a {@link ListenableFuture} of a {@link List} of {@link WorkInfo}s that provides 103 * information about the status of each {@link OneTimeWorkRequest} in this 104 * {@link WorkContinuation}, as well as their prerequisites. 105 * 106 * @return A {@link ListenableFuture} of a {@link List} of {@link WorkInfo}s 107 */ getWorkInfos()108 public abstract @NonNull ListenableFuture<List<WorkInfo>> getWorkInfos(); 109 110 /** 111 * Enqueues the instance of {@link WorkContinuation} on the background thread. 112 * 113 * @return An {@link Operation} that can be used to determine when the enqueue has completed 114 */ enqueue()115 public abstract @NonNull Operation enqueue(); 116 117 /** 118 * Combines multiple {@link WorkContinuation}s as prerequisites for a new WorkContinuation to 119 * allow for complex chaining. For example, to create a graph like this: 120 * 121 * <pre> 122 * A C 123 * | | 124 * B D 125 * | | 126 * +-------+ 127 * | 128 * E </pre> 129 * 130 * you would write the following: 131 * 132 * <pre> 133 * {@code 134 * WorkContinuation left = workManager.beginWith(A).then(B); 135 * WorkContinuation right = workManager.beginWith(C).then(D); 136 * WorkContinuation final = WorkContinuation.combine(Arrays.asList(left, right)).then(E); 137 * final.enqueue();}</pre> 138 * 139 * @param continuations One or more {@link WorkContinuation}s that are prerequisites for the 140 * return value 141 * @return A {@link WorkContinuation} that allows further chaining 142 */ combine(@onNull List<WorkContinuation> continuations)143 public static @NonNull WorkContinuation combine(@NonNull List<WorkContinuation> continuations) { 144 return continuations.get(0).combineInternal(continuations); 145 } 146 147 /** 148 */ 149 @SuppressWarnings("HiddenAbstractMethod") 150 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) combineInternal( @onNull List<WorkContinuation> continuations)151 protected abstract @NonNull WorkContinuation combineInternal( 152 @NonNull List<WorkContinuation> continuations); 153 } 154