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.database.ContentObserver; 209911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamiltonimport android.os.Handler; 21a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackbornimport android.util.DebugUtils; 22a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 23a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackbornimport java.io.FileDescriptor; 24a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackbornimport java.io.PrintWriter; 259911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 269911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton/** 279525f2a72e2786f1b53927878dd8234859ea5c39Mark Doliner * A class that performs asynchronous loading of data. While Loaders are active 289911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * they should monitor the source of their data and deliver new results when the contents 299567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * change. See {@link android.app.LoaderManager} for more detail. 309911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 31247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p><b>Note on threading:</b> Clients of loaders should as a rule perform 32247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * any calls on to a Loader from the main thread of their process (that is, 33247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * the thread the Activity callbacks and other things occur on). Subclasses 34247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * of Loader (such as {@link AsyncTaskLoader}) will often perform their work 35247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * in a separate thread, but when delivering their results this too should 36247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * be done on the main thread.</p> 37247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * 38a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * <p>Subclasses generally must implement at least {@link #onStartLoading()}, 399567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * {@link #onStopLoading()}, {@link #onForceLoad()}, and {@link #onReset()}.</p> 409567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * 419567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * <p>Most implementations should not derive directly from this class, but 429567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * instead inherit from {@link AsyncTaskLoader}.</p> 43b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * 44b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <div class="special reference"> 45b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <h3>Developer Guides</h3> 46b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <p>For more information about using loaders, read the 479f52b7a4a8d4c8648095618f5fd4ee5cd2b6c917Mark Lu * <a href="{@docRoot}guide/components/loaders.html">Loaders</a> developer guide.</p> 48b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * </div> 49a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * 509911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param <D> The result returned when the load is complete 510a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * 521f4e67b6e17e9b86151140174491b2360bac82d9Ian Lake * @deprecated Use the <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> 531f4e67b6e17e9b86151140174491b2360bac82d9Ian Lake * {@link android.support.v4.content.Loader} 549911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 550a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake@Deprecated 56a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackbornpublic class Loader<D> { 579911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton int mId; 589911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton OnLoadCompleteListener<D> mListener; 59b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown OnLoadCanceledListener<D> mOnLoadCanceledListener; 609911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton Context mContext; 61a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn boolean mStarted = false; 62260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn boolean mAbandoned = false; 63a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn boolean mReset = true; 640e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn boolean mContentChanged = false; 65ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn boolean mProcessingChange = false; 669911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 677871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn /** 687871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * An implementation of a ContentObserver that takes care of connecting 697871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * it to the Loader to have the loader re-load its data when the observer 707871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * is told it has changed. You do not normally need to use this yourself; 717871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * it is used for you by {@link CursorLoader} to take care of executing 727871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * an update when the cursor's backing data changes. 730a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * 740a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * @deprecated Use {@link android.support.v4.content.Loader.ForceLoadContentObserver} 757871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn */ 760a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake @Deprecated 779911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public final class ForceLoadContentObserver extends ContentObserver { 789911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public ForceLoadContentObserver() { 799911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton super(new Handler()); 809911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 819911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 829911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton @Override 839911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public boolean deliverSelfNotifications() { 849911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton return true; 859911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 869911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 879911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton @Override 889911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public void onChange(boolean selfChange) { 89ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki onContentChanged(); 909911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 919911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 929911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 937871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn /** 947871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * Interface that is implemented to discover when a Loader has finished 957871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * loading its data. You do not normally need to implement this yourself; 967871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * it is used in the implementation of {@link android.app.LoaderManager} 977871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * to find out when a Loader it is managing has completed so that this can 987871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * be reported to its client. This interface should only be used if a 997871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn * Loader is not being used in conjunction with LoaderManager. 1000a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * 1010a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * @deprecated Use {@link android.support.v4.content.Loader.OnLoadCompleteListener} 1027871badd5d4d29d80207e9cc09a0681f26a151d0Dianne Hackborn */ 1030a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake @Deprecated 1049911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public interface OnLoadCompleteListener<D> { 1059911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 1069911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Called on the thread that created the Loader when the load is complete. 1079911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 1089911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param loader the loader that completed the load 1099911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param data the result of the load 1109911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1119911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public void onLoadComplete(Loader<D> loader, D data); 1129911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1139911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 1149911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 115b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Interface that is implemented to discover when a Loader has been canceled 116b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * before it finished loading its data. You do not normally need to implement 117b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * this yourself; it is used in the implementation of {@link android.app.LoaderManager} 118b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * to find out when a Loader it is managing has been canceled so that it 119b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * can schedule the next Loader. This interface should only be used if a 120b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Loader is not being used in conjunction with LoaderManager. 1210a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * 1220a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake * @deprecated Use {@link android.support.v4.content.Loader.OnLoadCanceledListener} 123b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 1240a1feb819234ae7fc8cc32aa1dc5929823b0a5bcIan Lake @Deprecated 125b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown public interface OnLoadCanceledListener<D> { 126b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 127b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Called on the thread that created the Loader when the load is canceled. 128b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 129b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * @param loader the loader that canceled the load 130b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 131b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown public void onLoadCanceled(Loader<D> loader); 132b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 133b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown 134b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 1359567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * Stores away the application context associated with context. 1369567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * Since Loaders can be used across multiple activities it's dangerous to 1379567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * store the context directly; always use {@link #getContext()} to retrieve 1389567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * the Loader's Context, don't use the constructor argument directly. 1399567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * The Context returned by {@link #getContext} is safe to use across 1409567a66a5e6f49dd8495fb5f6e2efb9f32e84b35Dianne Hackborn * Activity instances. 1419911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 1429911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param context used to retrieve the application context. 1439911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1449911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public Loader(Context context) { 1459911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton mContext = context.getApplicationContext(); 1469911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1479911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 1489911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 1499911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Sends the result of the load to the registered listener. Should only be called by subclasses. 1509911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 151247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Must be called from the process's main thread. 1529911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 1539911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @param data the result of the load 1549911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1559911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public void deliverResult(D data) { 1569911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton if (mListener != null) { 1579911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton mListener.onLoadComplete(this, data); 1589911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1599911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1609911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 1619911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 162b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Informs the registered {@link OnLoadCanceledListener} that the load has been canceled. 163b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Should only be called by subclasses. 164b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 165b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Must be called from the process's main thread. 166b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 167b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown public void deliverCancellation() { 168b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown if (mOnLoadCanceledListener != null) { 169b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown mOnLoadCanceledListener.onLoadCanceled(this); 170b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 171b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 172b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown 173b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 1749911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @return an application context retrieved from the Context passed to the constructor. 1759911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1769911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public Context getContext() { 1779911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton return mContext; 1789911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1799911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 1809911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 1819911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * @return the ID of this loader 1829911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1839911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public int getId() { 1849911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton return mId; 1859911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1869911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 1879911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 188247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Registers a class that will receive callbacks when a load is complete. 189247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * The callback will be called on the process's main thread so it's safe to 190247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * pass the results to widgets. 191ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki * 192247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Must be called from the process's main thread. 1939911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 1949911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public void registerListener(int id, OnLoadCompleteListener<D> listener) { 1959911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton if (mListener != null) { 1969911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton throw new IllegalStateException("There is already a listener registered"); 1979911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 1989911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton mListener = listener; 1999911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton mId = id; 2009911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 2019911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 2029911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 203247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Remove a listener that was previously added with {@link #registerListener}. 204247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * 205247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Must be called from the process's main thread. 2069911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 2079911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton public void unregisterListener(OnLoadCompleteListener<D> listener) { 2089911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton if (mListener == null) { 2099911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton throw new IllegalStateException("No listener register"); 2109911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 2119911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton if (mListener != listener) { 2129911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton throw new IllegalArgumentException("Attempting to unregister the wrong listener"); 2139911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 2149911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton mListener = null; 2159911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton } 2169911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 2179911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 218b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Registers a listener that will receive callbacks when a load is canceled. 219b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * The callback will be called on the process's main thread so it's safe to 220b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * pass the results to widgets. 221b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 222b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Must be called from the process's main thread. 223b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 224b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * @param listener The listener to register. 225b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 226b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown public void registerOnLoadCanceledListener(OnLoadCanceledListener<D> listener) { 227b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown if (mOnLoadCanceledListener != null) { 228b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown throw new IllegalStateException("There is already a listener registered"); 229b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 230b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown mOnLoadCanceledListener = listener; 231b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 232b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown 233b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 234b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Unregisters a listener that was previously added with 235b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * {@link #registerOnLoadCanceledListener}. 236b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 237b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Must be called from the process's main thread. 238b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 239b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * @param listener The listener to unregister. 240b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 241b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown public void unregisterOnLoadCanceledListener(OnLoadCanceledListener<D> listener) { 242b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown if (mOnLoadCanceledListener == null) { 243b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown throw new IllegalStateException("No listener register"); 244b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 245b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown if (mOnLoadCanceledListener != listener) { 246b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown throw new IllegalArgumentException("Attempting to unregister the wrong listener"); 247b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 248b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown mOnLoadCanceledListener = null; 249b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 250b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown 251b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 252a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Return whether this load has been started. That is, its {@link #startLoading()} 253a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * has been called and no calls to {@link #stopLoading()} or 254a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * {@link #reset()} have yet been made. 255a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 256a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn public boolean isStarted() { 257a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn return mStarted; 258a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 259a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 260a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 261260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * Return whether this loader has been abandoned. In this state, the 262260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * loader <em>must not</em> report any new data, and <em>must</em> keep 263260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * its last reported data valid until it is finally reset. 264260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn */ 265260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn public boolean isAbandoned() { 266260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn return mAbandoned; 267260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn } 268260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn 269260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn /** 270a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Return whether this load has been reset. That is, either the loader 271a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * has not yet been started for the first time, or its {@link #reset()} 272a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * has been called. 273a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 274a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn public boolean isReset() { 275a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn return mReset; 276a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 277a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 278a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 2792c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * This function will normally be called for you automatically by 2802c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * {@link android.app.LoaderManager} when the associated fragment/activity 2812c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * is being started. When using a Loader with {@link android.app.LoaderManager}, 2822c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * you <em>must not</em> call this method yourself, or you will conflict 2832c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * with its management of the Loader. 2842c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * 285247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Starts an asynchronous load of the Loader's data. When the result 286247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * is ready the callbacks will be called on the process's main thread. 287247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * If a previous load has been completed and is still valid 288247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * the result may be passed to the callbacks immediately. 289247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * The loader will monitor the source of 290247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * the data set and may deliver future callbacks if the source changes. 291247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * Calling {@link #stopLoading} will stop the delivery of callbacks. 2929911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 293a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * <p>This updates the Loader's internal state so that 294a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * {@link #isStarted()} and {@link #isReset()} will return the correct 295a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * values, and then calls the implementation's {@link #onStartLoading()}. 296a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * 297247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Must be called from the process's main thread. 298a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 2990e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn public final void startLoading() { 300a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn mStarted = true; 301a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn mReset = false; 302260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn mAbandoned = false; 303a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn onStartLoading(); 304a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 305a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 306a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 307a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Subclasses must implement this to take care of loading their data, 308a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * as per {@link #startLoading()}. This is not called by clients directly, 309a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * but as a result of a call to {@link #startLoading()}. 3109911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 311a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn protected void onStartLoading() { 312a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 3139911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 3149911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 315b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Attempt to cancel the current load task. 316b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Must be called on the main thread of the process. 317b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 318b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * <p>Cancellation is not an immediate operation, since the load is performed 319b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * in a background thread. If there is currently a load in progress, this 320b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * method requests that the load be canceled, and notes this is the case; 321b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * once the background thread has completed its work its remaining state 322b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * will be cleared. If another load request comes in during this time, 323b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * it will be held until the canceled load is complete. 324b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 325b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * @return Returns <tt>false</tt> if the task could not be canceled, 326b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * typically because it has already completed normally, or 327b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * because {@link #startLoading()} hasn't been called; returns 328b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * <tt>true</tt> otherwise. When <tt>true</tt> is returned, the task 329b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * is still running and the {@link OnLoadCanceledListener} will be called 330b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * when the task completes. 331b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 332b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown public boolean cancelLoad() { 333b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown return onCancelLoad(); 334b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 335b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown 336b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 337b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * Subclasses must implement this to take care of requests to {@link #cancelLoad()}. 338b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * This will always be called from the process's main thread. 339b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * 340b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * @return Returns <tt>false</tt> if the task could not be canceled, 341b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * typically because it has already completed normally, or 342b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * because {@link #startLoading()} hasn't been called; returns 343b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * <tt>true</tt> otherwise. When <tt>true</tt> is returned, the task 344b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * is still running and the {@link OnLoadCanceledListener} will be called 345b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown * when the task completes. 346b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown */ 347b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown protected boolean onCancelLoad() { 348b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown return false; 349b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown } 350b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown 351b19a71a20adb48c084e87d06a1e6b0dcb49170f5Jeff Brown /** 3529911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously 353a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * loaded data set and load a new one. This simply calls through to the 3540e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * implementation's {@link #onForceLoad()}. You generally should only call this 3550e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * when the loader is started -- that is, {@link #isStarted()} returns true. 356a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * 357247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Must be called from the process's main thread. 3589911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 359247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public void forceLoad() { 360a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn onForceLoad(); 361a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 3629911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 3639911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 364a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Subclasses must implement this to take care of requests to {@link #forceLoad()}. 365247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * This will always be called from the process's main thread. 366a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 367a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn protected void onForceLoad() { 368a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 369a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 370a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 3712c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * This function will normally be called for you automatically by 3722c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * {@link android.app.LoaderManager} when the associated fragment/activity 3732c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * is being stopped. When using a Loader with {@link android.app.LoaderManager}, 3742c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * you <em>must not</em> call this method yourself, or you will conflict 3752c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * with its management of the Loader. 3762c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * 3772c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * <p>Stops delivery of updates until the next time {@link #startLoading()} is called. 3780e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * Implementations should <em>not</em> invalidate their data at this point -- 3790e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * clients are still free to use the last data the loader reported. They will, 3800e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * however, typically stop reporting new data if the data changes; they can 3810e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * still monitor for changes, but must not report them to the client until and 3820e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * if {@link #startLoading()} is later called. 3839911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 384a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * <p>This updates the Loader's internal state so that 385a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * {@link #isStarted()} will return the correct 386a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * value, and then calls the implementation's {@link #onStopLoading()}. 387a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * 388247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Must be called from the process's main thread. 3899911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 390247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public void stopLoading() { 391a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn mStarted = false; 392a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn onStopLoading(); 393a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 394a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 395a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 396a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Subclasses must implement this to take care of stopping their loader, 397a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * as per {@link #stopLoading()}. This is not called by clients directly, 398a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * but as a result of a call to {@link #stopLoading()}. 399247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * This will always be called from the process's main thread. 400a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 401a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn protected void onStopLoading() { 402a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 4039911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton 4049911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton /** 4052c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * This function will normally be called for you automatically by 4062c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * {@link android.app.LoaderManager} when restarting a Loader. When using 4072c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * a Loader with {@link android.app.LoaderManager}, 4082c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * you <em>must not</em> call this method yourself, or you will conflict 4092c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * with its management of the Loader. 4102c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * 411260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * Tell the Loader that it is being abandoned. This is called prior 412260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * to {@link #reset} to have it retain its current data but not report 413260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * any new data. 414260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn */ 415260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn public void abandon() { 416260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn mAbandoned = true; 417260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn onAbandon(); 418260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn } 419260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn 420260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn /** 421260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * Subclasses implement this to take care of being abandoned. This is 422260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * an optional intermediate state prior to {@link #onReset()} -- it means that 423260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * the client is no longer interested in any new data from the loader, 424260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * so the loader must not report any further updates. However, the 425260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * loader <em>must</em> keep its last reported data valid until the final 426260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * {@link #onReset()} happens. You can retrieve the current abandoned 427260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn * state with {@link #isAbandoned}. 428260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn */ 429c64ff3782c71ce7b5a92b7d91199a922ea0a37d9Jeff Brown protected void onAbandon() { 430260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn } 431260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn 432260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn /** 4332c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * This function will normally be called for you automatically by 4342c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * {@link android.app.LoaderManager} when destroying a Loader. When using 4352c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * a Loader with {@link android.app.LoaderManager}, 4362c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * you <em>must not</em> call this method yourself, or you will conflict 4372c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * with its management of the Loader. 4382c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * 439c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn * Resets the state of the Loader. The Loader should at this point free 440c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn * all of its resources, since it may never be called again; however, its 441c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn * {@link #startLoading()} may later be called at which point it must be 442c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn * able to start running again. 4439911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton * 444a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * <p>This updates the Loader's internal state so that 445a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * {@link #isStarted()} and {@link #isReset()} will return the correct 446a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * values, and then calls the implementation's {@link #onReset()}. 447a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * 448247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Must be called from the process's main thread. 4499911b7f83db2e960f72345e6d50df2b77ca75e3fJeff Hamilton */ 450247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public void reset() { 451a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn onReset(); 452a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn mReset = true; 453a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn mStarted = false; 454260c3c77d9b340164e055f87002c64d78da6e836Dianne Hackborn mAbandoned = false; 4550e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn mContentChanged = false; 456ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn mProcessingChange = false; 457c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn } 458c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn 459c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn /** 460a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Subclasses must implement this to take care of resetting their loader, 461a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * as per {@link #reset()}. This is not called by clients directly, 462a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * but as a result of a call to {@link #reset()}. 463247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * This will always be called from the process's main thread. 464c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn */ 465a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn protected void onReset() { 466c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn } 467ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki 468ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki /** 4690e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * Take the current flag indicating whether the loader's content had 4700e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * changed while it was stopped. If it had, true is returned and the 4710e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * flag is cleared. 4720e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn */ 4730e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn public boolean takeContentChanged() { 4740e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn boolean res = mContentChanged; 4750e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn mContentChanged = false; 476ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn mProcessingChange |= res; 4770e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn return res; 4780e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn } 479ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn 480ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn /** 481ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * Commit that you have actually fully processed a content change that 482ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * was returned by {@link #takeContentChanged}. This is for use with 483ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * {@link #rollbackContentChanged()} to handle situations where a load 484ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * is cancelled. Call this when you have completely processed a load 485ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * without it being cancelled. 486ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn */ 487ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn public void commitContentChanged() { 488ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn mProcessingChange = false; 489ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn } 490ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn 491ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn /** 492ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * Report that you have abandoned the processing of a content change that 493ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * was returned by {@link #takeContentChanged()} and would like to rollback 494ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * to the state where there is again a pending content change. This is 495ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * to handle the case where a data load due to a content change has been 496ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn * canceled before its data was delivered back to the loader. 497ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn */ 498ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn public void rollbackContentChanged() { 499ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn if (mProcessingChange) { 5004be84bb10cf0bd998f33d9e5a7ca42cf8e072ad7Adam Powell onContentChanged(); 501ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn } 502ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn } 503ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn 5040e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn /** 5050e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * Called when {@link ForceLoadContentObserver} detects a change. The 5060e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * default implementation checks to see if the loader is currently started; 5070e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * if so, it simply calls {@link #forceLoad()}; otherwise, it sets a flag 5080e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn * so that {@link #takeContentChanged()} returns true. 509ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki * 510247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn * <p>Must be called from the process's main thread. 511ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki */ 512ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki public void onContentChanged() { 5130e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn if (mStarted) { 5140e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn forceLoad(); 5150e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn } else { 5160e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn // This loader has been stopped, so we don't want to load 5170e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn // new data right now... but keep track of it changing to 5180e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn // refresh later if we start again. 5190e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn mContentChanged = true; 5200e3b8f421dfcc5363f234eb1b76479cb2fb2e8eeDianne Hackborn } 521ec37c88570bdd1b94309ad613395295f13449c3fMakoto Onuki } 522a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 523a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 524a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * For debugging, converts an instance of the Loader's data class to 525a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * a string that can be printed. Must handle a null data. 526a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 527a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn public String dataToString(D data) { 528a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn StringBuilder sb = new StringBuilder(64); 529a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn DebugUtils.buildShortClassTag(data, sb); 530a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn sb.append("}"); 531a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn return sb.toString(); 532a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 533a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 534a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn @Override 535a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn public String toString() { 536a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn StringBuilder sb = new StringBuilder(64); 537a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn DebugUtils.buildShortClassTag(this, sb); 538a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn sb.append(" id="); 539a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn sb.append(mId); 540a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn sb.append("}"); 541a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn return sb.toString(); 542a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 543a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn 544a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn /** 545a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * Print the Loader's state into the given stream. 546a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * 547a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * @param prefix Text to print at the front of each line. 548a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * @param fd The raw file descriptor that the dump is being sent to. 549a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * @param writer A PrintWriter to which the dump is to be set. 550a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn * @param args Additional arguments to the dump request. 551a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn */ 552a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 553a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn writer.print(prefix); writer.print("mId="); writer.print(mId); 554a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn writer.print(" mListener="); writer.println(mListener); 555ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn if (mStarted || mContentChanged || mProcessingChange) { 556ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn writer.print(prefix); writer.print("mStarted="); writer.print(mStarted); 557ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn writer.print(" mContentChanged="); writer.print(mContentChanged); 558ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn writer.print(" mProcessingChange="); writer.println(mProcessingChange); 559ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn } 560ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn if (mAbandoned || mReset) { 561ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn writer.print(prefix); writer.print("mAbandoned="); writer.print(mAbandoned); 562ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn writer.print(" mReset="); writer.println(mReset); 563ca614f78bed7eebf9dbfd77ba5720a0b5eeed816Dianne Hackborn } 564a2ea747faaf5fcd437afbaaf4085cfc29e7c16b8Dianne Hackborn } 5651f4e67b6e17e9b86151140174491b2360bac82d9Ian Lake} 566