AsyncTaskLoader.java revision 0e3b8f421dfcc5363f234eb1b76479cb2fb2e8ee
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content;
18
19import android.os.AsyncTask;
20
21/**
22 * Abstract Loader that provides an {@link AsyncTask} to do the work.
23 *
24 * @param <D> the data type to be loaded.
25 */
26public abstract class AsyncTaskLoader<D> extends Loader<D> {
27    final class LoadTask extends AsyncTask<Void, Void, D> {
28
29        private D result;
30
31        /* Runs on a worker thread */
32        @Override
33        protected D doInBackground(Void... params) {
34            result = AsyncTaskLoader.this.loadInBackground();
35            return result;
36        }
37
38        /* Runs on the UI thread */
39        @Override
40        protected void onPostExecute(D data) {
41            AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
42        }
43
44        @Override
45        protected void onCancelled() {
46            AsyncTaskLoader.this.onCancelled(result);
47        }
48    }
49
50    LoadTask mTask;
51
52    public AsyncTaskLoader(Context context) {
53        super(context);
54    }
55
56    @Override
57    protected void onForceLoad() {
58        super.onForceLoad();
59        cancelLoad();
60        mTask = new LoadTask();
61        mTask.execute((Void[]) null);
62    }
63
64    /**
65     * Attempt to cancel the current load task. See {@link AsyncTask#cancel(boolean)}
66     * for more info.
67     *
68     * @return <tt>false</tt> if the task could not be canceled,
69     *         typically because it has already completed normally, or
70     *         because {@link #startLoading()} hasn't been called, and
71     *         <tt>true</tt> otherwise
72     */
73    public boolean cancelLoad() {
74        if (mTask != null) {
75            boolean cancelled = mTask.cancel(false);
76            mTask = null;
77            return cancelled;
78        }
79        return false;
80    }
81
82    /**
83     * Called if the task was canceled before it was completed.  Gives the class a chance
84     * to properly dispose of the result.
85     */
86    public void onCancelled(D data) {
87    }
88
89    void dispatchOnLoadComplete(LoadTask task, D data) {
90        if (mTask != task) {
91            onCancelled(data);
92        } else {
93            mTask = null;
94            deliverResult(data);
95        }
96    }
97
98    /**
99     * Called on a worker thread to perform the actual load. Implementations should not deliver the
100     * results directly, but should return them from this method, which will eventually end up
101     * calling deliverResult on the UI thread. If implementations need to process
102     * the results on the UI thread they may override deliverResult and do so
103     * there.
104     *
105     * @return the result of the load
106     */
107    public abstract D loadInBackground();
108}
109