Loader.java revision 9911b7f83db2e960f72345e6d50df2b77ca75e3f
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.database.ContentObserver; 20import android.os.Handler; 21 22/** 23 * An abstract class that performs asynchronous loading of data. While Loaders are active 24 * they should monitor the source of their data and deliver new results when the contents 25 * change. 26 * 27 * @param <D> The result returned when the load is complete 28 */ 29public abstract class Loader<D> { 30 int mId; 31 OnLoadCompleteListener<D> mListener; 32 Context mContext; 33 34 public final class ForceLoadContentObserver extends ContentObserver { 35 public ForceLoadContentObserver() { 36 super(new Handler()); 37 } 38 39 @Override 40 public boolean deliverSelfNotifications() { 41 return true; 42 } 43 44 @Override 45 public void onChange(boolean selfChange) { 46 forceLoad(); 47 } 48 } 49 50 public interface OnLoadCompleteListener<D> { 51 /** 52 * Called on the thread that created the Loader when the load is complete. 53 * 54 * @param loader the loader that completed the load 55 * @param data the result of the load 56 */ 57 public void onLoadComplete(Loader<D> loader, D data); 58 } 59 60 /** 61 * Stores away the application context associated with context. Since Loaders can be used 62 * across multiple activities it's dangerous to store the context directly. 63 * 64 * @param context used to retrieve the application context. 65 */ 66 public Loader(Context context) { 67 mContext = context.getApplicationContext(); 68 } 69 70 /** 71 * Sends the result of the load to the registered listener. Should only be called by subclasses. 72 * 73 * Must be called from the UI thread. 74 * 75 * @param data the result of the load 76 */ 77 public void deliverResult(D data) { 78 if (mListener != null) { 79 mListener.onLoadComplete(this, data); 80 } 81 } 82 83 /** 84 * @return an application context retrieved from the Context passed to the constructor. 85 */ 86 public Context getContext() { 87 return mContext; 88 } 89 90 /** 91 * @return the ID of this loader 92 */ 93 public int getId() { 94 return mId; 95 } 96 97 /** 98 * Registers a class that will receive callbacks when a load is complete. The callbacks will 99 * be called on the UI thread so it's safe to pass the results to widgets. 100 * 101 * Must be called from the UI thread 102 */ 103 public void registerListener(int id, OnLoadCompleteListener<D> listener) { 104 if (mListener != null) { 105 throw new IllegalStateException("There is already a listener registered"); 106 } 107 mListener = listener; 108 mId = id; 109 } 110 111 /** 112 * Must be called from the UI thread 113 */ 114 public void unregisterListener(OnLoadCompleteListener<D> listener) { 115 if (mListener == null) { 116 throw new IllegalStateException("No listener register"); 117 } 118 if (mListener != listener) { 119 throw new IllegalArgumentException("Attempting to unregister the wrong listener"); 120 } 121 mListener = null; 122 } 123 124 /** 125 * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks 126 * will be called on the UI thread. If a previous load has been completed and is still valid 127 * the result may be passed to the callbacks immediately. The loader will monitor the source of 128 * the data set and may deliver future callbacks if the source changes. Calling 129 * {@link #stopLoading} will stop the delivery of callbacks. 130 * 131 * Must be called from the UI thread 132 */ 133 public abstract void startLoading(); 134 135 /** 136 * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously 137 * loaded data set and load a new one. 138 */ 139 public abstract void forceLoad(); 140 141 /** 142 * Stops delivery of updates until the next time {@link #startLoading()} is called 143 * 144 * Must be called from the UI thread 145 */ 146 public abstract void stopLoading(); 147 148 /** 149 * Destroys the loader and frees its resources, making it unusable. 150 * 151 * Must be called from the UI thread 152 */ 153 public abstract void destroy(); 154}