FileDocCategorySizeDatePackage
AsyncTaskLoader.javaAPI DocAndroid 5.1 API10434Thu Mar 12 22:22:56 GMT 2015android.support.v4.content

AsyncTaskLoader

public abstract class AsyncTaskLoader extends Loader
Static library support version of the framework's {@link android.content.AsyncTaskLoader}. Used to write apps that run on platforms prior to Android 3.0. When running on Android 3.0 or above, this implementation is still used; it does not try to switch to the framework's implementation. See the framework SDK documentation for a class overview.

Fields Summary
static final String
TAG
static final boolean
DEBUG
volatile LoadTask
mTask
volatile LoadTask
mCancellingTask
long
mUpdateThrottle
long
mLastLoadCompleteTime
android.os.Handler
mHandler
Constructors Summary
public AsyncTaskLoader(android.content.Context context)


       
        super(context);
    
Methods Summary
public booleancancelLoad()
Attempt to cancel the current load task. See {@link android.os.AsyncTask#cancel(boolean)} for more info. Must be called on the main thread of the process.

Cancelling is not an immediate operation, since the load is performed in a background thread. If there is currently a load in progress, this method requests that the load be cancelled, and notes this is the case; once the background thread has completed its work its remaining state will be cleared. If another load request comes in during this time, it will be held until the cancelled load is complete.

return
Returns false if the task could not be cancelled, typically because it has already completed normally, or because {@link #startLoading()} hasn't been called; returns true otherwise.

        if (DEBUG) Log.v(TAG, "cancelLoad: mTask=" + mTask);
        if (mTask != null) {
            if (mCancellingTask != null) {
                // There was a pending task already waiting for a previous
                // one being canceled; just drop it.
                if (DEBUG) Log.v(TAG,
                        "cancelLoad: still waiting for cancelled task; dropping next");
                if (mTask.waiting) {
                    mTask.waiting = false;
                    mHandler.removeCallbacks(mTask);
                }
                mTask = null;
                return false;
            } else if (mTask.waiting) {
                // There is a task, but it is waiting for the time it should
                // execute.  We can just toss it.
                if (DEBUG) Log.v(TAG, "cancelLoad: task is waiting, dropping it");
                mTask.waiting = false;
                mHandler.removeCallbacks(mTask);
                mTask = null;
                return false;
            } else {
                boolean cancelled = mTask.cancel(false);
                if (DEBUG) Log.v(TAG, "cancelLoad: cancelled=" + cancelled);
                if (cancelled) {
                    mCancellingTask = mTask;
                }
                mTask = null;
                return cancelled;
            }
        }
        return false;
    
voiddispatchOnCancelled(android.support.v4.content.AsyncTaskLoader$LoadTask task, D data)

        onCanceled(data);
        if (mCancellingTask == task) {
            if (DEBUG) Log.v(TAG, "Cancelled task is now canceled!");
            rollbackContentChanged();
            mLastLoadCompleteTime = SystemClock.uptimeMillis();
            mCancellingTask = null;
            executePendingTask();
        }
    
voiddispatchOnLoadComplete(android.support.v4.content.AsyncTaskLoader$LoadTask task, D data)

        if (mTask != task) {
            if (DEBUG) Log.v(TAG, "Load complete of old task, trying to cancel");
            dispatchOnCancelled(task, data);
        } else {
            if (isAbandoned()) {
                // This cursor has been abandoned; just cancel the new data.
                onCanceled(data);
            } else {
                commitContentChanged();
                mLastLoadCompleteTime = SystemClock.uptimeMillis();
                mTask = null;
                if (DEBUG) Log.v(TAG, "Delivering result");
                deliverResult(data);
            }
        }
    
public voiddump(java.lang.String prefix, java.io.FileDescriptor fd, java.io.PrintWriter writer, java.lang.String[] args)

        super.dump(prefix, fd, writer, args);
        if (mTask != null) {
            writer.print(prefix); writer.print("mTask="); writer.print(mTask);
                    writer.print(" waiting="); writer.println(mTask.waiting);
        }
        if (mCancellingTask != null) {
            writer.print(prefix); writer.print("mCancellingTask="); writer.print(mCancellingTask);
                    writer.print(" waiting="); writer.println(mCancellingTask.waiting);
        }
        if (mUpdateThrottle != 0) {
            writer.print(prefix); writer.print("mUpdateThrottle=");
                    TimeUtils.formatDuration(mUpdateThrottle, writer);
                    writer.print(" mLastLoadCompleteTime=");
                    TimeUtils.formatDuration(mLastLoadCompleteTime,
                            SystemClock.uptimeMillis(), writer);
                    writer.println();
        }
    
voidexecutePendingTask()

        if (mCancellingTask == null && mTask != null) {
            if (mTask.waiting) {
                mTask.waiting = false;
                mHandler.removeCallbacks(mTask);
            }
            if (mUpdateThrottle > 0) {
                long now = SystemClock.uptimeMillis();
                if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
                    // Not yet time to do another load.
                    if (DEBUG) Log.v(TAG, "Waiting until "
                            + (mLastLoadCompleteTime+mUpdateThrottle)
                            + " to execute: " + mTask);
                    mTask.waiting = true;
                    mHandler.postAtTime(mTask, mLastLoadCompleteTime+mUpdateThrottle);
                    return;
                }
            }
            if (DEBUG) Log.v(TAG, "Executing: " + mTask);
            mTask.executeOnExecutor(ModernAsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
        }
    
public abstract DloadInBackground()

public voidonCanceled(D data)
Called if the task was canceled before it was completed. Gives the class a chance to properly dispose of the result.

    
protected voidonForceLoad()

        super.onForceLoad();
        cancelLoad();
        mTask = new LoadTask();
        if (DEBUG) Log.v(TAG, "Preparing load: mTask=" + mTask);
        executePendingTask();
    
protected DonLoadInBackground()
Called on a worker thread to perform the actual load. Implementations should not deliver the result directly, but should return them from this method, which will eventually end up calling {@link #deliverResult} on the UI thread. If implementations need to process the results on the UI thread they may override {@link #deliverResult} and do so there.

return
Implementations must return the result of their load operation.

        return loadInBackground();
    
public voidsetUpdateThrottle(long delayMS)
Set amount to throttle updates by. This is the minimum time from when the last {@link #onLoadInBackground()} call has completed until a new load is scheduled.

param
delayMS Amount of delay, in milliseconds.

        mUpdateThrottle = delayMS;
        if (delayMS != 0) {
            mHandler = new Handler();
        }
    
public voidwaitForLoader()
Locks the current thread until the loader completes the current load operation. Returns immediately if there is no load operation running. Should not be called from the UI thread: calling it from the UI thread would cause a deadlock.

Use for testing only. Never call this from a UI thread.

hide

        LoadTask task = mTask;
        if (task != null) {
            try {
                task.done.await();
            } catch (InterruptedException e) {
                // Ignore
            }
        }