AsyncTaskLoader.java revision 327fbd2c8fa294b919475feb4c74a74ee1981e02
19911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton/* 29911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Copyright (C) 2010 The Android Open Source Project 39911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 49911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License"); 59911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * you may not use this file except in compliance with the License. 69911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * You may obtain a copy of the License at 79911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 89911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * http://www.apache.org/licenses/LICENSE-2.0 99911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 109911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Unless required by applicable law or agreed to in writing, software 119911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS, 129911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * See the License for the specific language governing permissions and 149911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * limitations under the License. 159911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 169911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 179911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamiltonpackage android.content; 189911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 199911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamiltonimport android.os.AsyncTask; 20247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackbornimport android.os.Handler; 21247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackbornimport android.os.SystemClock; 22540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackbornimport android.util.Slog; 23247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackbornimport android.util.TimeUtils; 24cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov 25247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackbornimport java.io.FileDescriptor; 26247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackbornimport java.io.PrintWriter; 2759d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikovimport java.util.concurrent.CountDownLatch; 289911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 299911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton/** 309911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Abstract Loader that provides an {@link AsyncTask} to do the work. 31bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov * 329911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param <D> the data type to be loaded. 339911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 349911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamiltonpublic abstract class AsyncTaskLoader<D> extends Loader<D> { 35540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn static final String TAG = "AsyncTaskLoader"; 36540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn static final boolean DEBUG = false; 37cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov 38247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn final class LoadTask extends AsyncTask<Void, Void, D> implements Runnable { 39bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov 40247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn D result; 41247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn boolean waiting; 42bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov 4359d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov private CountDownLatch done = new CountDownLatch(1); 4459d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov 459911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /* Runs on a worker thread */ 469911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton @Override 479911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton protected D doInBackground(Void... params) { 48540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, this + " >>> doInBackground"); 49247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn result = AsyncTaskLoader.this.onLoadInBackground(); 50540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, this + " <<< doInBackground"); 51bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov return result; 529911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 539911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 549911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /* Runs on the UI thread */ 559911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton @Override 569911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton protected void onPostExecute(D data) { 57540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, this + " onPostExecute"); 5859d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov try { 5959d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); 6059d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov } finally { 6159d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov done.countDown(); 6259d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov } 639911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 64bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov 65bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov @Override 66bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov protected void onCancelled() { 67540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, this + " onCancelled"); 6859d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov try { 6959d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov AsyncTaskLoader.this.dispatchOnCancelled(this, result); 7059d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov } finally { 7159d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov done.countDown(); 7259d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov } 73247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 74247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 75247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn @Override 76247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public void run() { 77247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn waiting = false; 78247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn AsyncTaskLoader.this.executePendingTask(); 79bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov } 809911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 819911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 82cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov volatile LoadTask mTask; 83247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn volatile LoadTask mCancellingTask; 84247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 85247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn long mUpdateThrottle; 86247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn long mLastLoadCompleteTime = -10000; 87247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn Handler mHandler; 889911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 899911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public AsyncTaskLoader(Context context) { 909911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton super(context); 919911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 929911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 93247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn /** 94247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Set amount to throttle updates by. This is the minimum time from 95247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * when the last {@link #onLoadInBackground()} call has completed until 96247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * a new load is scheduled. 97247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * 98247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * @param delayMS Amount of delay, in milliseconds. 99247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn */ 100247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public void setUpdateThrottle(long delayMS) { 101247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mUpdateThrottle = delayMS; 102247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (delayMS != 0) { 103247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mHandler = new Handler(); 104247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 105247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 106247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 1079911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton @Override 108a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn protected void onForceLoad() { 1090e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn super.onForceLoad(); 110bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov cancelLoad(); 1119911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton mTask = new LoadTask(); 112540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "Preparing load: mTask=" + mTask); 113247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn executePendingTask(); 1149911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1159911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 1169911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 1179911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Attempt to cancel the current load task. See {@link AsyncTask#cancel(boolean)} 118247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * for more info. Must be called on the main thread of the process. 119247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * 120247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Cancelling is not an immediate operation, since the load is performed 121247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * in a background thread. If there is currently a load in progress, this 122247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * method requests that the load be cancelled, and notes this is the case; 123247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * once the background thread has completed its work its remaining state 124247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * will be cleared. If another load request comes in during this time, 125247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * it will be held until the cancelled load is complete. 1269911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 127247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * @return Returns <tt>false</tt> if the task could not be cancelled, 1289911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * typically because it has already completed normally, or 129247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * because {@link #startLoading()} hasn't been called; returns 130247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <tt>true</tt> otherwise. 1319911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1329911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public boolean cancelLoad() { 133540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "cancelLoad: mTask=" + mTask); 1349911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton if (mTask != null) { 135247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mCancellingTask != null) { 136247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn // There was a pending task already waiting for a previous 137247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn // one being canceled; just drop it. 138540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, 139540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn "cancelLoad: still waiting for cancelled task; dropping next"); 140247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mTask.waiting) { 141247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask.waiting = false; 142247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mHandler.removeCallbacks(mTask); 143247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 144247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask = null; 145247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn return false; 146247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } else if (mTask.waiting) { 147247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn // There is a task, but it is waiting for the time it should 148247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn // execute. We can just toss it. 149540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "cancelLoad: task is waiting, dropping it"); 150247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask.waiting = false; 151247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mHandler.removeCallbacks(mTask); 152247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask = null; 153247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn return false; 154247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } else { 155247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn boolean cancelled = mTask.cancel(false); 156540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "cancelLoad: cancelled=" + cancelled); 157247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (cancelled) { 158247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mCancellingTask = mTask; 159247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 160247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask = null; 161247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn return cancelled; 162247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 1639911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1649911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton return false; 1659911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 166bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov 167bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov /** 168bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov * Called if the task was canceled before it was completed. Gives the class a chance 169bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov * to properly dispose of the result. 170bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov */ 171327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public void onCanceled(D data) { 172327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn onCancelled(data); 173bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov } 174bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov 175327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn @Deprecated 176327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public void onCancelled(D data) { 177327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn } 178327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn 179247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn void executePendingTask() { 180247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mCancellingTask == null && mTask != null) { 181247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mTask.waiting) { 182247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask.waiting = false; 183247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mHandler.removeCallbacks(mTask); 184247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 185247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mUpdateThrottle > 0) { 186247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn long now = SystemClock.uptimeMillis(); 187247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (now < (mLastLoadCompleteTime+mUpdateThrottle)) { 188247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn // Not yet time to do another load. 189540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "Waiting until " 190540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn + (mLastLoadCompleteTime+mUpdateThrottle) 191540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn + " to execute: " + mTask); 192247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask.waiting = true; 193247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mHandler.postAtTime(mTask, mLastLoadCompleteTime+mUpdateThrottle); 194247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn return; 195247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 196247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 197540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "Executing: " + mTask); 198247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mTask.execute((Void[]) null); 199247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 200247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 201247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 202247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn void dispatchOnCancelled(LoadTask task, D data) { 203327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn onCanceled(data); 204247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mCancellingTask == task) { 205540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "Cancelled task is now canceled!"); 206247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mLastLoadCompleteTime = SystemClock.uptimeMillis(); 207247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mCancellingTask = null; 208247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn executePendingTask(); 209247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 210247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 211247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 2120e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn void dispatchOnLoadComplete(LoadTask task, D data) { 2130e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn if (mTask != task) { 214540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "Load complete of old task, trying to cancel"); 215247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn dispatchOnCancelled(task, data); 2160e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn } else { 217247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn mLastLoadCompleteTime = SystemClock.uptimeMillis(); 2180e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn mTask = null; 219540f86aa42877ac73f6f2f24dac49382432aa078Dianne Hackborn if (DEBUG) Slog.v(TAG, "Delivering result"); 2200e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn deliverResult(data); 2210e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn } 2229911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 2239911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 2249911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 225247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn */ 226247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public abstract D loadInBackground(); 227247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 228247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn /** 2299911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Called on a worker thread to perform the actual load. Implementations should not deliver the 230247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * result directly, but should return them from this method, which will eventually end up 231247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * calling {@link #deliverResult} on the UI thread. If implementations need to process 232247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * the results on the UI thread they may override {@link #deliverResult} and do so 233e6c6d09a7eb9a7cd6e94c164e75a08dc499fd577Jeff Hamilton * there. 2349911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 235247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * @return Implementations must return the result of their load operation. 2369911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 237247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn protected D onLoadInBackground() { 238247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn return loadInBackground(); 239247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 240cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov 241cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov /** 242cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov * Locks the current thread until the loader completes the current load 243cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov * operation. Returns immediately if there is no load operation running. 24459d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov * Should not be called from the UI thread: calling it from the UI 24559d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov * thread would cause a deadlock. 246cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov * <p> 247247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Use for testing only. <b>Never</b> call this from a UI thread. 248cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov */ 249cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov public void waitForLoader() { 250cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov LoadTask task = mTask; 251cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov if (task != null) { 252cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov try { 25359d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov task.done.await(); 254cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov } catch (InterruptedException e) { 25559d8edd09dc88cc0eb629bdee711a004d300f2faDmitri Plotnikov // Ignore 256cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov } 257cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov } 258cd3676e7b835653b04d4f66251a63749e7603f5bDmitri Plotnikov } 259247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 260247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn @Override 261247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 262247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn super.dump(prefix, fd, writer, args); 263247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mTask != null) { 264247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.print(prefix); writer.print("mTask="); writer.print(mTask); 265247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.print(" waiting="); writer.println(mTask.waiting); 266247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 267247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mCancellingTask != null) { 268247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.print(prefix); writer.print("mCancellingTask="); writer.print(mCancellingTask); 269247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.print(" waiting="); writer.println(mCancellingTask.waiting); 270247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 271247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn if (mUpdateThrottle != 0) { 272247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.print(prefix); writer.print("mUpdateThrottle="); 273247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn TimeUtils.formatDuration(mUpdateThrottle, writer); 274247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.print(" mLastLoadCompleteTime="); 275247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn TimeUtils.formatDuration(mLastLoadCompleteTime, 276247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn SystemClock.uptimeMillis(), writer); 277247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn writer.println(); 278247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 279247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 2809911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton} 281