1333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick/* 2333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project 3333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 4333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 5333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * you may not use this file except in compliance with the License. 6333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * You may obtain a copy of the License at 7333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 8333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * http://www.apache.org/licenses/LICENSE-2.0 9333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 10333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Unless required by applicable law or agreed to in writing, software 11333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS, 12333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * See the License for the specific language governing permissions and 14333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * limitations under the License. 15333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick */ 16333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 17333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrickpackage android.app; 18333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 19333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrickimport java.util.concurrent.ConcurrentLinkedQueue; 20333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrickimport java.util.concurrent.ExecutorService; 21333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrickimport java.util.concurrent.Executors; 22333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 23333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick/** 24333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Internal utility class to keep track of process-global work that's 25333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * outstanding and hasn't been finished yet. 26333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 27333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * This was created for writing SharedPreference edits out 28333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * asynchronously so we'd have a mechanism to wait for the writes in 29333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Activity.onPause and similar places, but we may use this mechanism 30333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * for other things in the future. 31333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 32333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * @hide 33333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick */ 34333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrickpublic class QueuedWork { 35333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 36333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick // The set of Runnables that will finish or wait on any async 37333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick // activities started by the application. 38333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick private static final ConcurrentLinkedQueue<Runnable> sPendingWorkFinishers = 39333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick new ConcurrentLinkedQueue<Runnable>(); 40333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 41333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick private static ExecutorService sSingleThreadExecutor = null; // lazy, guarded by class 42333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 43333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick /** 44333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Returns a single-thread Executor shared by the entire process, 45333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * creating it if necessary. 46333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick */ 47333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick public static ExecutorService singleThreadExecutor() { 48333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick synchronized (QueuedWork.class) { 49333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick if (sSingleThreadExecutor == null) { 50333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick // TODO: can we give this single thread a thread name? 51333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick sSingleThreadExecutor = Executors.newSingleThreadExecutor(); 52333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 53333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick return sSingleThreadExecutor; 54333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 55333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 56333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 57333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick /** 58333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Add a runnable to finish (or wait for) a deferred operation 59333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * started in this context earlier. Typically finished by e.g. 60333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * an Activity#onPause. Used by SharedPreferences$Editor#startCommit(). 61333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 62333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Note that this doesn't actually start it running. This is just 63333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * a scratch set for callers doing async work to keep updated with 64333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * what's in-flight. In the common case, caller code 65333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * (e.g. SharedPreferences) will pretty quickly call remove() 66333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * after an add(). The only time these Runnables are run is from 67333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * waitToFinish(), below. 68333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick */ 69333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick public static void add(Runnable finisher) { 70333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick sPendingWorkFinishers.add(finisher); 71333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 72333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 73333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick public static void remove(Runnable finisher) { 74333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick sPendingWorkFinishers.remove(finisher); 75333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 76333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick 77333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick /** 78333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Finishes or waits for async operations to complete. 79333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * (e.g. SharedPreferences$Editor#startCommit writes) 80333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * 81333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * Is called from the Activity base class's onPause(), after 82333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * BroadcastReceiver's onReceive, after Service command handling, 83333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick * etc. (so async work is never lost) 84333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick */ 85333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick public static void waitToFinish() { 86333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick Runnable toFinish; 87333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick while ((toFinish = sPendingWorkFinishers.poll()) != null) { 88333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick toFinish.run(); 89333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 90333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick } 91e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn 92e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn /** 93e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn * Returns true if there is pending work to be done. Note that the 94e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn * result is out of data as soon as you receive it, so be careful how you 95e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn * use it. 96e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn */ 97e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn public static boolean hasPendingWork() { 98e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn return !sPendingWorkFinishers.isEmpty(); 99e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn } 100e829fef63957a23b61cdb01bb692a17a041ff2dcDianne Hackborn 101333b8cba996c8ebb8ca55ebfc5cc536bdd64af94Brad Fitzpatrick} 102