AsyncTaskLoader.java revision a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8
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;
209911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
219911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton/**
229911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Abstract Loader that provides an {@link AsyncTask} to do the work.
23bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov *
249911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param <D> the data type to be loaded.
259911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */
269911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamiltonpublic abstract class AsyncTaskLoader<D> extends Loader<D> {
279911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    final class LoadTask extends AsyncTask<Void, Void, D> {
28bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov
29bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov        private D result;
30bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov
319911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        /* Runs on a worker thread */
329911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        @Override
339911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        protected D doInBackground(Void... params) {
34bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            result = AsyncTaskLoader.this.loadInBackground();
35bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            return result;
369911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        }
379911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
389911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        /* Runs on the UI thread */
399911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        @Override
409911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        protected void onPostExecute(D data) {
419911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton            AsyncTaskLoader.this.dispatchOnLoadComplete(data);
429911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        }
43bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov
44bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov        @Override
45bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov        protected void onCancelled() {
46bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            AsyncTaskLoader.this.onCancelled(result);
47bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov        }
489911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    }
499911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
509911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    LoadTask mTask;
519911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
529911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    public AsyncTaskLoader(Context context) {
539911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        super(context);
549911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    }
559911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
569911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    @Override
57a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn    protected void onForceLoad() {
58bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov        cancelLoad();
599911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        mTask = new LoadTask();
609911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        mTask.execute((Void[]) null);
619911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    }
629911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
639911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    /**
649911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     * Attempt to cancel the current load task. See {@link AsyncTask#cancel(boolean)}
659911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     * for more info.
669911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     *
679911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     * @return <tt>false</tt> if the task could not be canceled,
689911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     *         typically because it has already completed normally, or
699911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     *         because {@link #startLoading()} hasn't been called, and
709911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     *         <tt>true</tt> otherwise
719911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     */
729911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    public boolean cancelLoad() {
739911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        if (mTask != null) {
74bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            boolean cancelled = mTask.cancel(false);
75bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            mTask = null;
76bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            return cancelled;
779911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        }
789911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        return false;
799911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    }
80bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov
81bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov    /**
82bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov     * Called if the task was canceled before it was completed.  Gives the class a chance
83bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov     * to properly dispose of the result.
84bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov     */
85bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov    public void onCancelled(D data) {
86bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov    }
87bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov
889911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    void dispatchOnLoadComplete(D data) {
899911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        mTask = null;
909911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton        deliverResult(data);
919911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    }
929911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton
939911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    /**
949911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     * Called on a worker thread to perform the actual load. Implementations should not deliver the
95e6c6d09a7eb9a7cd6e94c164e75a08dc499fd577Jeff Hamilton     * results directly, but should return them from this method, which will eventually end up
96bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov     * calling deliverResult on the UI thread. If implementations need to process
977860b10d1687b7102a14f321d327620bb4191fa6Jeff Hamilton     * the results on the UI thread they may override deliverResult and do so
98e6c6d09a7eb9a7cd6e94c164e75a08dc499fd577Jeff Hamilton     * there.
999911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     *
1009911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     * @return the result of the load
1019911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton     */
1029911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton    public abstract D loadInBackground();
1039911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton}
104