1 /* 2 * Copyright (C) 2006 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 17 package android.app; 18 19 import java.util.ArrayList; 20 21 import android.content.ComponentCallbacks; 22 import android.content.ComponentCallbacks2; 23 import android.content.Context; 24 import android.content.ContextWrapper; 25 import android.content.res.Configuration; 26 import android.os.Bundle; 27 28 /** 29 * Base class for those who need to maintain global application state. You can 30 * provide your own implementation by specifying its name in your 31 * AndroidManifest.xml's <application> tag, which will cause that class 32 * to be instantiated for you when the process for your application/package is 33 * created. 34 * 35 * <p class="note">There is normally no need to subclass Application. In 36 * most situation, static singletons can provide the same functionality in a 37 * more modular way. If your singleton needs a global context (for example 38 * to register broadcast receivers), the function to retrieve it can be 39 * given a {@link android.content.Context} which internally uses 40 * {@link android.content.Context#getApplicationContext() Context.getApplicationContext()} 41 * when first constructing the singleton.</p> 42 */ 43 public class Application extends ContextWrapper implements ComponentCallbacks2 { 44 private ArrayList<ComponentCallbacks> mComponentCallbacks = 45 new ArrayList<ComponentCallbacks>(); 46 private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = 47 new ArrayList<ActivityLifecycleCallbacks>(); 48 49 /** @hide */ 50 public LoadedApk mLoadedApk; 51 52 public interface ActivityLifecycleCallbacks { 53 void onActivityCreated(Activity activity, Bundle savedInstanceState); 54 void onActivityStarted(Activity activity); 55 void onActivityResumed(Activity activity); 56 void onActivityPaused(Activity activity); 57 void onActivityStopped(Activity activity); 58 void onActivitySaveInstanceState(Activity activity, Bundle outState); 59 void onActivityDestroyed(Activity activity); 60 } 61 62 public Application() { 63 super(null); 64 } 65 66 /** 67 * Called when the application is starting, before any other application 68 * objects have been created. Implementations should be as quick as 69 * possible (for example using lazy initialization of state) since the time 70 * spent in this function directly impacts the performance of starting the 71 * first activity, service, or receiver in a process. 72 * If you override this method, be sure to call super.onCreate(). 73 */ 74 public void onCreate() { 75 } 76 77 /** 78 * This method is for use in emulated process environments. It will 79 * never be called on a production Android device, where processes are 80 * removed by simply killing them; no user code (including this callback) 81 * is executed when doing so. 82 */ 83 public void onTerminate() { 84 } 85 86 public void onConfigurationChanged(Configuration newConfig) { 87 Object[] callbacks = collectComponentCallbacks(); 88 if (callbacks != null) { 89 for (int i=0; i<callbacks.length; i++) { 90 ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig); 91 } 92 } 93 } 94 95 public void onLowMemory() { 96 Object[] callbacks = collectComponentCallbacks(); 97 if (callbacks != null) { 98 for (int i=0; i<callbacks.length; i++) { 99 ((ComponentCallbacks)callbacks[i]).onLowMemory(); 100 } 101 } 102 } 103 104 public void onTrimMemory(int level) { 105 Object[] callbacks = collectComponentCallbacks(); 106 if (callbacks != null) { 107 for (int i=0; i<callbacks.length; i++) { 108 Object c = callbacks[i]; 109 if (c instanceof ComponentCallbacks2) { 110 ((ComponentCallbacks2)c).onTrimMemory(level); 111 } 112 } 113 } 114 } 115 116 public void registerComponentCallbacks(ComponentCallbacks callback) { 117 synchronized (mComponentCallbacks) { 118 mComponentCallbacks.add(callback); 119 } 120 } 121 122 public void unregisterComponentCallbacks(ComponentCallbacks callback) { 123 synchronized (mComponentCallbacks) { 124 mComponentCallbacks.remove(callback); 125 } 126 } 127 128 public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { 129 synchronized (mActivityLifecycleCallbacks) { 130 mActivityLifecycleCallbacks.add(callback); 131 } 132 } 133 134 public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { 135 synchronized (mActivityLifecycleCallbacks) { 136 mActivityLifecycleCallbacks.remove(callback); 137 } 138 } 139 140 // ------------------ Internal API ------------------ 141 142 /** 143 * @hide 144 */ 145 /* package */ final void attach(Context context) { 146 attachBaseContext(context); 147 mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; 148 } 149 150 /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) { 151 Object[] callbacks = collectActivityLifecycleCallbacks(); 152 if (callbacks != null) { 153 for (int i=0; i<callbacks.length; i++) { 154 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity, 155 savedInstanceState); 156 } 157 } 158 } 159 160 /* package */ void dispatchActivityStarted(Activity activity) { 161 Object[] callbacks = collectActivityLifecycleCallbacks(); 162 if (callbacks != null) { 163 for (int i=0; i<callbacks.length; i++) { 164 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity); 165 } 166 } 167 } 168 169 /* package */ void dispatchActivityResumed(Activity activity) { 170 Object[] callbacks = collectActivityLifecycleCallbacks(); 171 if (callbacks != null) { 172 for (int i=0; i<callbacks.length; i++) { 173 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity); 174 } 175 } 176 } 177 178 /* package */ void dispatchActivityPaused(Activity activity) { 179 Object[] callbacks = collectActivityLifecycleCallbacks(); 180 if (callbacks != null) { 181 for (int i=0; i<callbacks.length; i++) { 182 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity); 183 } 184 } 185 } 186 187 /* package */ void dispatchActivityStopped(Activity activity) { 188 Object[] callbacks = collectActivityLifecycleCallbacks(); 189 if (callbacks != null) { 190 for (int i=0; i<callbacks.length; i++) { 191 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity); 192 } 193 } 194 } 195 196 /* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) { 197 Object[] callbacks = collectActivityLifecycleCallbacks(); 198 if (callbacks != null) { 199 for (int i=0; i<callbacks.length; i++) { 200 ((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity, 201 outState); 202 } 203 } 204 } 205 206 /* package */ void dispatchActivityDestroyed(Activity activity) { 207 Object[] callbacks = collectActivityLifecycleCallbacks(); 208 if (callbacks != null) { 209 for (int i=0; i<callbacks.length; i++) { 210 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity); 211 } 212 } 213 } 214 215 private Object[] collectComponentCallbacks() { 216 Object[] callbacks = null; 217 synchronized (mComponentCallbacks) { 218 if (mComponentCallbacks.size() > 0) { 219 callbacks = mComponentCallbacks.toArray(); 220 } 221 } 222 return callbacks; 223 } 224 225 private Object[] collectActivityLifecycleCallbacks() { 226 Object[] callbacks = null; 227 synchronized (mActivityLifecycleCallbacks) { 228 if (mActivityLifecycleCallbacks.size() > 0) { 229 callbacks = mActivityLifecycleCallbacks.toArray(); 230 } 231 } 232 return callbacks; 233 } 234 } 235