1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/* 2cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project 3cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 4cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * you may not use this file except in compliance with the License. 6cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * You may obtain a copy of the License at 7cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 8cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 10cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * See the License for the specific language governing permissions and 14cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * limitations under the License. 15cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 16cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 17cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpackage android.support.v4.content; 18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 19cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.content.Context; 20cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Handler; 21cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.SystemClock; 22cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.support.v4.util.TimeUtils; 23cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Log; 24cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 25cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.FileDescriptor; 26cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.PrintWriter; 27cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.concurrent.CountDownLatch; 28cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 29cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 30cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Static library support version of the framework's {@link android.content.AsyncTaskLoader}. 31cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Used to write apps that run on platforms prior to Android 3.0. When running 32cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on Android 3.0 or above, this implementation is still used; it does not try 33cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to switch to the framework's implementation. See the framework SDK 34cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * documentation for a class overview. 35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 36cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpublic abstract class AsyncTaskLoader<D> extends Loader<D> { 37cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TAG = "AsyncTaskLoader"; 38cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final boolean DEBUG = false; 39cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 40fbabff99ccbcb576c713991c5db5dec21a0d0ce0Dianne Hackborn final class LoadTask extends ModernAsyncTask<Void, Void, D> implements Runnable { 41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 42cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn D result; 43cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean waiting; 44cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 45cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn private CountDownLatch done = new CountDownLatch(1); 46cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 47cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /* Runs on a worker thread */ 48cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 49cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn protected D doInBackground(Void... params) { 50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, this + " >>> doInBackground"); 51cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn result = AsyncTaskLoader.this.onLoadInBackground(); 52cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, this + " <<< doInBackground"); 53cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return result; 54cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 55cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 56cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /* Runs on the UI thread */ 57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 58cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn protected void onPostExecute(D data) { 59cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, this + " onPostExecute"); 60cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn try { 61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); 62cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } finally { 63cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn done.countDown(); 64cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 65cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 66cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 67cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 68cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn protected void onCancelled() { 69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, this + " onCancelled"); 70cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn try { 71cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn AsyncTaskLoader.this.dispatchOnCancelled(this, result); 72cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } finally { 73cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn done.countDown(); 74cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 75cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 76cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void run() { 79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn waiting = false; 80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn AsyncTaskLoader.this.executePendingTask(); 81cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn volatile LoadTask mTask; 85cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn volatile LoadTask mCancellingTask; 86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn long mUpdateThrottle; 88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn long mLastLoadCompleteTime = -10000; 89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Handler mHandler; 90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public AsyncTaskLoader(Context context) { 92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn super(context); 93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Set amount to throttle updates by. This is the minimum time from 97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * when the last {@link #onLoadInBackground()} call has completed until 98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * a new load is scheduled. 99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param delayMS Amount of delay, in milliseconds. 101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void setUpdateThrottle(long delayMS) { 103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mUpdateThrottle = delayMS; 104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (delayMS != 0) { 105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mHandler = new Handler(); 106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn protected void onForceLoad() { 111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn super.onForceLoad(); 112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn cancelLoad(); 113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask = new LoadTask(); 114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Preparing load: mTask=" + mTask); 115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn executePendingTask(); 116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 1190574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * Attempt to cancel the current load task. See {@link android.os.AsyncTask#cancel(boolean)} 120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * for more info. Must be called on the main thread of the process. 121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Cancelling is not an immediate operation, since the load is performed 123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * in a background thread. If there is currently a load in progress, this 124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * method requests that the load be cancelled, and notes this is the case; 125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * once the background thread has completed its work its remaining state 126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be cleared. If another load request comes in during this time, 127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * it will be held until the cancelled load is complete. 128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns <tt>false</tt> if the task could not be cancelled, 130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * typically because it has already completed normally, or 131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * because {@link #startLoading()} hasn't been called; returns 132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <tt>true</tt> otherwise. 133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean cancelLoad() { 135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "cancelLoad: mTask=" + mTask); 136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mTask != null) { 137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCancellingTask != null) { 138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // There was a pending task already waiting for a previous 139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // one being canceled; just drop it. 140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, 141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "cancelLoad: still waiting for cancelled task; dropping next"); 142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mTask.waiting) { 143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask.waiting = false; 144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mHandler.removeCallbacks(mTask); 145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask = null; 147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else if (mTask.waiting) { 149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // There is a task, but it is waiting for the time it should 150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // execute. We can just toss it. 151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "cancelLoad: task is waiting, dropping it"); 152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask.waiting = false; 153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mHandler.removeCallbacks(mTask); 154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask = null; 155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean cancelled = mTask.cancel(false); 158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "cancelLoad: cancelled=" + cancelled); 159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (cancelled) { 160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCancellingTask = mTask; 161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask = null; 163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return cancelled; 164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Called if the task was canceled before it was completed. Gives the class a chance 171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to properly dispose of the result. 172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void onCanceled(D data) { 174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void executePendingTask() { 177cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCancellingTask == null && mTask != null) { 178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mTask.waiting) { 179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask.waiting = false; 180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mHandler.removeCallbacks(mTask); 181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mUpdateThrottle > 0) { 183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn long now = SystemClock.uptimeMillis(); 184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (now < (mLastLoadCompleteTime+mUpdateThrottle)) { 185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Not yet time to do another load. 186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Waiting until " 187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + (mLastLoadCompleteTime+mUpdateThrottle) 188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + " to execute: " + mTask); 189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask.waiting = true; 190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mHandler.postAtTime(mTask, mLastLoadCompleteTime+mUpdateThrottle); 191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Executing: " + mTask); 195fbabff99ccbcb576c713991c5db5dec21a0d0ce0Dianne Hackborn mTask.executeOnExecutor(ModernAsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 198cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void dispatchOnCancelled(LoadTask task, D data) { 200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn onCanceled(data); 201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCancellingTask == task) { 202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Cancelled task is now canceled!"); 20380a0a3a33e3f6c27da4681a4f02eb2c6aae1fd40Dianne Hackborn rollbackContentChanged(); 204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mLastLoadCompleteTime = SystemClock.uptimeMillis(); 205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCancellingTask = null; 206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn executePendingTask(); 207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void dispatchOnLoadComplete(LoadTask task, D data) { 211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mTask != task) { 212cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Load complete of old task, trying to cancel"); 213cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dispatchOnCancelled(task, data); 214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (isAbandoned()) { 216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // This cursor has been abandoned; just cancel the new data. 217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn onCanceled(data); 218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 21980a0a3a33e3f6c27da4681a4f02eb2c6aae1fd40Dianne Hackborn commitContentChanged(); 220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mLastLoadCompleteTime = SystemClock.uptimeMillis(); 221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mTask = null; 222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Delivering result"); 223cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn deliverResult(data); 224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract D loadInBackground(); 231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Called on a worker thread to perform the actual load. Implementations should not deliver the 234cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * result directly, but should return them from this method, which will eventually end up 235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * calling {@link #deliverResult} on the UI thread. If implementations need to process 236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the results on the UI thread they may override {@link #deliverResult} and do so 237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * there. 238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Implementations must return the result of their load operation. 240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn protected D onLoadInBackground() { 242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return loadInBackground(); 243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Locks the current thread until the loader completes the current load 247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * operation. Returns immediately if there is no load operation running. 248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Should not be called from the UI thread: calling it from the UI 249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * thread would cause a deadlock. 250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p> 251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Use for testing only. <b>Never</b> call this from a UI thread. 252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @hide 254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 255cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void waitForLoader() { 256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn LoadTask task = mTask; 257cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (task != null) { 258cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn try { 259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn task.done.await(); 260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } catch (InterruptedException e) { 261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Ignore 262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 263cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 265cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn super.dump(prefix, fd, writer, args); 269cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mTask != null) { 270cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("mTask="); writer.print(mTask); 271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" waiting="); writer.println(mTask.waiting); 272cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 273cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCancellingTask != null) { 274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("mCancellingTask="); writer.print(mCancellingTask); 275cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" waiting="); writer.println(mCancellingTask.waiting); 276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 277cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mUpdateThrottle != 0) { 278cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("mUpdateThrottle="); 279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn TimeUtils.formatDuration(mUpdateThrottle, writer); 280cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mLastLoadCompleteTime="); 281cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn TimeUtils.formatDuration(mLastLoadCompleteTime, 282cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn SystemClock.uptimeMillis(), writer); 283cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(); 284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 286cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 287