2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import java.util.concurrent.ConcurrentLinkedQueue;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Executors;
24 * Internal utility class to keep track of process-global work that's
25 * outstanding and hasn't been finished yet.
27 * This was created for writing SharedPreference edits out
28 * asynchronously so we'd have a mechanism to wait for the writes in
29 * Activity.onPause and similar places, but we may use this mechanism
30 * for other things in the future.
34 public class QueuedWork {
36 // The set of Runnables that will finish or wait on any async
37 // activities started by the application.
38 private static final ConcurrentLinkedQueue<Runnable> sPendingWorkFinishers =
39 new ConcurrentLinkedQueue<Runnable>();
41 private static ExecutorService sSingleThreadExecutor = null; // lazy, guarded by class
44 * Returns a single-thread Executor shared by the entire process,
45 * creating it if necessary.
47 public static ExecutorService singleThreadExecutor() {
48 synchronized (QueuedWork.class) {
49 if (sSingleThreadExecutor == null) {
50 // TODO: can we give this single thread a thread name?
51 sSingleThreadExecutor = Executors.newSingleThreadExecutor();
53 return sSingleThreadExecutor;
58 * Add a runnable to finish (or wait for) a deferred operation
59 * started in this context earlier. Typically finished by e.g.
60 * an Activity#onPause. Used by SharedPreferences$Editor#startCommit().
62 * Note that this doesn't actually start it running. This is just
63 * a scratch set for callers doing async work to keep updated with
64 * what's in-flight. In the common case, caller code
65 * (e.g. SharedPreferences) will pretty quickly call remove()
66 * after an add(). The only time these Runnables are run is from
67 * waitToFinish(), below.
69 public static void add(Runnable finisher) {
70 sPendingWorkFinishers.add(finisher);
73 public static void remove(Runnable finisher) {
74 sPendingWorkFinishers.remove(finisher);
78 * Finishes or waits for async operations to complete.
79 * (e.g. SharedPreferences$Editor#startCommit writes)
81 * Is called from the Activity base class's onPause(), after
82 * BroadcastReceiver's onReceive, after Service command handling,
83 * etc. (so async work is never lost)
85 public static void waitToFinish() {
87 while ((toFinish = sPendingWorkFinishers.poll()) != null) {