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