1 /* 2 * Copyright (C) 2017 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 17 package androidx.arch.core.executor; 18 19 import androidx.annotation.RestrictTo; 20 21 import org.jspecify.annotations.NonNull; 22 import org.jspecify.annotations.Nullable; 23 24 import java.util.concurrent.Executor; 25 26 /** 27 * A static class that serves as a central point to execute common tasks. 28 * <p> 29 * 30 */ 31 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) 32 public class ArchTaskExecutor extends TaskExecutor { 33 private static volatile ArchTaskExecutor sInstance; 34 35 private @NonNull TaskExecutor mDelegate; 36 37 private final @NonNull TaskExecutor mDefaultTaskExecutor; 38 39 private static final @NonNull Executor sMainThreadExecutor = 40 command -> getInstance().postToMainThread(command); 41 42 private static final @NonNull Executor sIOThreadExecutor = 43 command -> getInstance().executeOnDiskIO(command); 44 ArchTaskExecutor()45 private ArchTaskExecutor() { 46 mDefaultTaskExecutor = new DefaultTaskExecutor(); 47 mDelegate = mDefaultTaskExecutor; 48 } 49 50 /** 51 * Returns an instance of the task executor. 52 * 53 * @return The singleton ArchTaskExecutor. 54 */ getInstance()55 public static @NonNull ArchTaskExecutor getInstance() { 56 if (sInstance != null) { 57 return sInstance; 58 } 59 synchronized (ArchTaskExecutor.class) { 60 if (sInstance == null) { 61 sInstance = new ArchTaskExecutor(); 62 } 63 } 64 return sInstance; 65 } 66 67 /** 68 * Sets a delegate to handle task execution requests. 69 * <p> 70 * If you have a common executor, you can set it as the delegate and App Toolkit components will 71 * use your executors. You may also want to use this for your tests. 72 * <p> 73 * Calling this method with {@code null} sets it to the default TaskExecutor. 74 * 75 * @param taskExecutor The task executor to handle task requests. 76 */ setDelegate(@ullable TaskExecutor taskExecutor)77 public void setDelegate(@Nullable TaskExecutor taskExecutor) { 78 mDelegate = taskExecutor == null ? mDefaultTaskExecutor : taskExecutor; 79 } 80 81 @Override executeOnDiskIO(@onNull Runnable runnable)82 public void executeOnDiskIO(@NonNull Runnable runnable) { 83 mDelegate.executeOnDiskIO(runnable); 84 } 85 86 @Override postToMainThread(@onNull Runnable runnable)87 public void postToMainThread(@NonNull Runnable runnable) { 88 mDelegate.postToMainThread(runnable); 89 } 90 getMainThreadExecutor()91 public static @NonNull Executor getMainThreadExecutor() { 92 return sMainThreadExecutor; 93 } 94 getIOThreadExecutor()95 public static @NonNull Executor getIOThreadExecutor() { 96 return sIOThreadExecutor; 97 } 98 99 @Override isMainThread()100 public boolean isMainThread() { 101 return mDelegate.isMainThread(); 102 } 103 } 104