|
1 /* |
|
2 * This is an adapted version of Android's original CursorLoader |
|
3 * without all the ContentProvider-specific bits. |
|
4 * |
|
5 * Copyright (C) 2011 The Android Open Source Project |
|
6 * |
|
7 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
8 * you may not use this file except in compliance with the License. |
|
9 * You may obtain a copy of the License at |
|
10 * |
|
11 * http://www.apache.org/licenses/LICENSE-2.0 |
|
12 * |
|
13 * Unless required by applicable law or agreed to in writing, software |
|
14 * distributed under the License is distributed on an "AS IS" BASIS, |
|
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
16 * See the License for the specific language governing permissions and |
|
17 * limitations under the License. |
|
18 */ |
|
19 |
|
20 package org.mozilla.gecko.home; |
|
21 |
|
22 import android.content.Context; |
|
23 import android.database.Cursor; |
|
24 import android.support.v4.content.AsyncTaskLoader; |
|
25 |
|
26 abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> { |
|
27 final ForceLoadContentObserver mObserver; |
|
28 Cursor mCursor; |
|
29 |
|
30 public SimpleCursorLoader(Context context) { |
|
31 super(context); |
|
32 mObserver = new ForceLoadContentObserver(); |
|
33 } |
|
34 |
|
35 /** |
|
36 * Loads the target cursor for this loader. This method is called |
|
37 * on a worker thread. |
|
38 */ |
|
39 protected abstract Cursor loadCursor(); |
|
40 |
|
41 /* Runs on a worker thread */ |
|
42 @Override |
|
43 public Cursor loadInBackground() { |
|
44 Cursor cursor = loadCursor(); |
|
45 |
|
46 if (cursor != null) { |
|
47 // Ensure the cursor window is filled |
|
48 cursor.getCount(); |
|
49 cursor.registerContentObserver(mObserver); |
|
50 } |
|
51 |
|
52 return cursor; |
|
53 } |
|
54 |
|
55 /* Runs on the UI thread */ |
|
56 @Override |
|
57 public void deliverResult(Cursor cursor) { |
|
58 if (isReset()) { |
|
59 // An async query came in while the loader is stopped |
|
60 if (cursor != null) { |
|
61 cursor.close(); |
|
62 } |
|
63 |
|
64 return; |
|
65 } |
|
66 |
|
67 Cursor oldCursor = mCursor; |
|
68 mCursor = cursor; |
|
69 |
|
70 if (isStarted()) { |
|
71 super.deliverResult(cursor); |
|
72 } |
|
73 |
|
74 if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { |
|
75 oldCursor.close(); |
|
76 } |
|
77 } |
|
78 |
|
79 /** |
|
80 * Starts an asynchronous load of the list data. When the result is ready the callbacks |
|
81 * will be called on the UI thread. If a previous load has been completed and is still valid |
|
82 * the result may be passed to the callbacks immediately. |
|
83 * |
|
84 * Must be called from the UI thread |
|
85 */ |
|
86 @Override |
|
87 protected void onStartLoading() { |
|
88 if (mCursor != null) { |
|
89 deliverResult(mCursor); |
|
90 } |
|
91 |
|
92 if (takeContentChanged() || mCursor == null) { |
|
93 forceLoad(); |
|
94 } |
|
95 } |
|
96 |
|
97 /** |
|
98 * Must be called from the UI thread |
|
99 */ |
|
100 @Override |
|
101 protected void onStopLoading() { |
|
102 // Attempt to cancel the current load task if possible. |
|
103 cancelLoad(); |
|
104 } |
|
105 |
|
106 @Override |
|
107 public void onCanceled(Cursor cursor) { |
|
108 if (cursor != null && !cursor.isClosed()) { |
|
109 cursor.close(); |
|
110 } |
|
111 } |
|
112 |
|
113 @Override |
|
114 protected void onReset() { |
|
115 super.onReset(); |
|
116 |
|
117 // Ensure the loader is stopped |
|
118 onStopLoading(); |
|
119 |
|
120 if (mCursor != null && !mCursor.isClosed()) { |
|
121 mCursor.close(); |
|
122 } |
|
123 |
|
124 mCursor = null; |
|
125 } |
|
126 } |