The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 19 | import java.util.ArrayList; |
| 20 | |
John Reck | add7026 | 2015-05-06 09:44:53 -0700 | [diff] [blame] | 21 | import android.annotation.CallSuper; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 22 | import android.content.ComponentCallbacks; |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 23 | import android.content.ComponentCallbacks2; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 24 | import android.content.Context; |
| 25 | import android.content.ContextWrapper; |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 26 | import android.content.Intent; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 27 | import android.content.res.Configuration; |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 28 | import android.os.Bundle; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 29 | |
| 30 | /** |
| 31 | * Base class for those who need to maintain global application state. You can |
| 32 | * provide your own implementation by specifying its name in your |
| 33 | * AndroidManifest.xml's <application> tag, which will cause that class |
| 34 | * to be instantiated for you when the process for your application/package is |
| 35 | * created. |
Dianne Hackborn | 7025d8e | 2010-11-01 09:49:37 -0700 | [diff] [blame] | 36 | * |
| 37 | * <p class="note">There is normally no need to subclass Application. In |
| 38 | * most situation, static singletons can provide the same functionality in a |
| 39 | * more modular way. If your singleton needs a global context (for example |
| 40 | * to register broadcast receivers), the function to retrieve it can be |
| 41 | * given a {@link android.content.Context} which internally uses |
| 42 | * {@link android.content.Context#getApplicationContext() Context.getApplicationContext()} |
| 43 | * when first constructing the singleton.</p> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 44 | */ |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 45 | public class Application extends ContextWrapper implements ComponentCallbacks2 { |
| 46 | private ArrayList<ComponentCallbacks> mComponentCallbacks = |
| 47 | new ArrayList<ComponentCallbacks>(); |
| 48 | private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = |
| 49 | new ArrayList<ActivityLifecycleCallbacks>(); |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 50 | private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null; |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 51 | |
Dianne Hackborn | 5fd2169 | 2011-06-07 14:09:47 -0700 | [diff] [blame] | 52 | /** @hide */ |
| 53 | public LoadedApk mLoadedApk; |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 54 | |
| 55 | public interface ActivityLifecycleCallbacks { |
| 56 | void onActivityCreated(Activity activity, Bundle savedInstanceState); |
| 57 | void onActivityStarted(Activity activity); |
| 58 | void onActivityResumed(Activity activity); |
| 59 | void onActivityPaused(Activity activity); |
| 60 | void onActivityStopped(Activity activity); |
| 61 | void onActivitySaveInstanceState(Activity activity, Bundle outState); |
| 62 | void onActivityDestroyed(Activity activity); |
| 63 | } |
| 64 | |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 65 | /** |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 66 | * Callback interface for use with {@link Application#registerOnProvideAssistDataListener} |
| 67 | * and {@link Application#unregisterOnProvideAssistDataListener}. |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 68 | */ |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 69 | public interface OnProvideAssistDataListener { |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 70 | /** |
| 71 | * This is called when the user is requesting an assist, to build a full |
| 72 | * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current |
| 73 | * application. You can override this method to place into the bundle anything |
| 74 | * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part |
| 75 | * of the assist Intent. |
| 76 | */ |
| 77 | public void onProvideAssistData(Activity activity, Bundle data); |
| 78 | } |
| 79 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 80 | public Application() { |
| 81 | super(null); |
| 82 | } |
| 83 | |
| 84 | /** |
Jacob Nordfalk | 8e61185 | 2012-01-31 22:23:46 +0100 | [diff] [blame] | 85 | * Called when the application is starting, before any activity, service, |
| 86 | * or receiver objects (excluding content providers) have been created. |
| 87 | * Implementations should be as quick as possible (for example using |
| 88 | * lazy initialization of state) since the time spent in this function |
| 89 | * directly impacts the performance of starting the first activity, |
| 90 | * service, or receiver in a process. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 91 | * If you override this method, be sure to call super.onCreate(). |
| 92 | */ |
John Reck | add7026 | 2015-05-06 09:44:53 -0700 | [diff] [blame] | 93 | @CallSuper |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 94 | public void onCreate() { |
| 95 | } |
| 96 | |
| 97 | /** |
Dianne Hackborn | 7025d8e | 2010-11-01 09:49:37 -0700 | [diff] [blame] | 98 | * This method is for use in emulated process environments. It will |
| 99 | * never be called on a production Android device, where processes are |
| 100 | * removed by simply killing them; no user code (including this callback) |
| 101 | * is executed when doing so. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 102 | */ |
John Reck | add7026 | 2015-05-06 09:44:53 -0700 | [diff] [blame] | 103 | @CallSuper |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 104 | public void onTerminate() { |
| 105 | } |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 106 | |
John Reck | add7026 | 2015-05-06 09:44:53 -0700 | [diff] [blame] | 107 | @CallSuper |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 108 | public void onConfigurationChanged(Configuration newConfig) { |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 109 | Object[] callbacks = collectComponentCallbacks(); |
| 110 | if (callbacks != null) { |
| 111 | for (int i=0; i<callbacks.length; i++) { |
| 112 | ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig); |
| 113 | } |
| 114 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 115 | } |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 116 | |
John Reck | add7026 | 2015-05-06 09:44:53 -0700 | [diff] [blame] | 117 | @CallSuper |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 118 | public void onLowMemory() { |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 119 | Object[] callbacks = collectComponentCallbacks(); |
| 120 | if (callbacks != null) { |
| 121 | for (int i=0; i<callbacks.length; i++) { |
| 122 | ((ComponentCallbacks)callbacks[i]).onLowMemory(); |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
John Reck | add7026 | 2015-05-06 09:44:53 -0700 | [diff] [blame] | 127 | @CallSuper |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 128 | public void onTrimMemory(int level) { |
| 129 | Object[] callbacks = collectComponentCallbacks(); |
| 130 | if (callbacks != null) { |
| 131 | for (int i=0; i<callbacks.length; i++) { |
| 132 | Object c = callbacks[i]; |
| 133 | if (c instanceof ComponentCallbacks2) { |
| 134 | ((ComponentCallbacks2)c).onTrimMemory(level); |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | public void registerComponentCallbacks(ComponentCallbacks callback) { |
| 141 | synchronized (mComponentCallbacks) { |
| 142 | mComponentCallbacks.add(callback); |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | public void unregisterComponentCallbacks(ComponentCallbacks callback) { |
| 147 | synchronized (mComponentCallbacks) { |
| 148 | mComponentCallbacks.remove(callback); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { |
| 153 | synchronized (mActivityLifecycleCallbacks) { |
| 154 | mActivityLifecycleCallbacks.add(callback); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { |
| 159 | synchronized (mActivityLifecycleCallbacks) { |
| 160 | mActivityLifecycleCallbacks.remove(callback); |
| 161 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 162 | } |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 163 | |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 164 | public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) { |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 165 | synchronized (this) { |
| 166 | if (mAssistCallbacks == null) { |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 167 | mAssistCallbacks = new ArrayList<OnProvideAssistDataListener>(); |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 168 | } |
| 169 | mAssistCallbacks.add(callback); |
| 170 | } |
| 171 | } |
| 172 | |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 173 | public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) { |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 174 | synchronized (this) { |
| 175 | if (mAssistCallbacks != null) { |
| 176 | mAssistCallbacks.remove(callback); |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 181 | // ------------------ Internal API ------------------ |
| 182 | |
| 183 | /** |
| 184 | * @hide |
| 185 | */ |
| 186 | /* package */ final void attach(Context context) { |
| 187 | attachBaseContext(context); |
Dianne Hackborn | 5fd2169 | 2011-06-07 14:09:47 -0700 | [diff] [blame] | 188 | mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 189 | } |
Dianne Hackborn | c68c913 | 2011-07-29 01:25:18 -0700 | [diff] [blame] | 190 | |
| 191 | /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) { |
| 192 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 193 | if (callbacks != null) { |
| 194 | for (int i=0; i<callbacks.length; i++) { |
| 195 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity, |
| 196 | savedInstanceState); |
| 197 | } |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | /* package */ void dispatchActivityStarted(Activity activity) { |
| 202 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 203 | if (callbacks != null) { |
| 204 | for (int i=0; i<callbacks.length; i++) { |
| 205 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity); |
| 206 | } |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | /* package */ void dispatchActivityResumed(Activity activity) { |
| 211 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 212 | if (callbacks != null) { |
| 213 | for (int i=0; i<callbacks.length; i++) { |
| 214 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity); |
| 215 | } |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | /* package */ void dispatchActivityPaused(Activity activity) { |
| 220 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 221 | if (callbacks != null) { |
| 222 | for (int i=0; i<callbacks.length; i++) { |
| 223 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity); |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | /* package */ void dispatchActivityStopped(Activity activity) { |
| 229 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 230 | if (callbacks != null) { |
| 231 | for (int i=0; i<callbacks.length; i++) { |
| 232 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity); |
| 233 | } |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | /* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) { |
| 238 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 239 | if (callbacks != null) { |
| 240 | for (int i=0; i<callbacks.length; i++) { |
| 241 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity, |
| 242 | outState); |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | /* package */ void dispatchActivityDestroyed(Activity activity) { |
| 248 | Object[] callbacks = collectActivityLifecycleCallbacks(); |
| 249 | if (callbacks != null) { |
| 250 | for (int i=0; i<callbacks.length; i++) { |
| 251 | ((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity); |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | private Object[] collectComponentCallbacks() { |
| 257 | Object[] callbacks = null; |
| 258 | synchronized (mComponentCallbacks) { |
| 259 | if (mComponentCallbacks.size() > 0) { |
| 260 | callbacks = mComponentCallbacks.toArray(); |
| 261 | } |
| 262 | } |
| 263 | return callbacks; |
| 264 | } |
| 265 | |
| 266 | private Object[] collectActivityLifecycleCallbacks() { |
| 267 | Object[] callbacks = null; |
| 268 | synchronized (mActivityLifecycleCallbacks) { |
| 269 | if (mActivityLifecycleCallbacks.size() > 0) { |
| 270 | callbacks = mActivityLifecycleCallbacks.toArray(); |
| 271 | } |
| 272 | } |
| 273 | return callbacks; |
| 274 | } |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 275 | |
| 276 | /* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) { |
| 277 | Object[] callbacks; |
| 278 | synchronized (this) { |
| 279 | if (mAssistCallbacks == null) { |
| 280 | return; |
| 281 | } |
| 282 | callbacks = mAssistCallbacks.toArray(); |
| 283 | } |
| 284 | if (callbacks != null) { |
| 285 | for (int i=0; i<callbacks.length; i++) { |
Dianne Hackborn | f977201 | 2013-04-18 14:10:03 -0700 | [diff] [blame] | 286 | ((OnProvideAssistDataListener)callbacks[i]).onProvideAssistData(activity, data); |
Dianne Hackborn | f9c5e0f | 2013-01-23 14:39:13 -0800 | [diff] [blame] | 287 | } |
| 288 | } |
| 289 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 290 | } |