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.annotation.CallSuper;
22 import android.content.ComponentCallbacks;
23 import android.content.ComponentCallbacks2;
24 import android.content.Context;
25 import android.content.ContextWrapper;
26 import android.content.Intent;
27 import android.content.res.Configuration;
28 import android.os.Bundle;
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.
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>
44  */
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>();
50     private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
51 
52     /** @hide */
53     public LoadedApk mLoadedApk;
54 
55     public interface ActivityLifecycleCallbacks {
onActivityCreated(Activity activity, Bundle savedInstanceState)56         void onActivityCreated(Activity activity, Bundle savedInstanceState);
onActivityStarted(Activity activity)57         void onActivityStarted(Activity activity);
onActivityResumed(Activity activity)58         void onActivityResumed(Activity activity);
onActivityPaused(Activity activity)59         void onActivityPaused(Activity activity);
onActivityStopped(Activity activity)60         void onActivityStopped(Activity activity);
onActivitySaveInstanceState(Activity activity, Bundle outState)61         void onActivitySaveInstanceState(Activity activity, Bundle outState);
onActivityDestroyed(Activity activity)62         void onActivityDestroyed(Activity activity);
63     }
64 
65     /**
66      * Callback interface for use with {@link Application#registerOnProvideAssistDataListener}
67      * and {@link Application#unregisterOnProvideAssistDataListener}.
68      */
69     public interface OnProvideAssistDataListener {
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          */
onProvideAssistData(Activity activity, Bundle data)77         public void onProvideAssistData(Activity activity, Bundle data);
78     }
79 
Application()80     public Application() {
81         super(null);
82     }
83 
84     /**
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.
91      * If you override this method, be sure to call super.onCreate().
92      */
93     @CallSuper
onCreate()94     public void onCreate() {
95     }
96 
97     /**
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.
102      */
103     @CallSuper
onTerminate()104     public void onTerminate() {
105     }
106 
107     @CallSuper
onConfigurationChanged(Configuration newConfig)108     public void onConfigurationChanged(Configuration newConfig) {
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         }
115     }
116 
117     @CallSuper
onLowMemory()118     public void onLowMemory() {
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 
127     @CallSuper
onTrimMemory(int level)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 
registerComponentCallbacks(ComponentCallbacks callback)140     public void registerComponentCallbacks(ComponentCallbacks callback) {
141         synchronized (mComponentCallbacks) {
142             mComponentCallbacks.add(callback);
143         }
144     }
145 
unregisterComponentCallbacks(ComponentCallbacks callback)146     public void unregisterComponentCallbacks(ComponentCallbacks callback) {
147         synchronized (mComponentCallbacks) {
148             mComponentCallbacks.remove(callback);
149         }
150     }
151 
registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback)152     public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
153         synchronized (mActivityLifecycleCallbacks) {
154             mActivityLifecycleCallbacks.add(callback);
155         }
156     }
157 
unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback)158     public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
159         synchronized (mActivityLifecycleCallbacks) {
160             mActivityLifecycleCallbacks.remove(callback);
161         }
162     }
163 
registerOnProvideAssistDataListener(OnProvideAssistDataListener callback)164     public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
165         synchronized (this) {
166             if (mAssistCallbacks == null) {
167                 mAssistCallbacks = new ArrayList<OnProvideAssistDataListener>();
168             }
169             mAssistCallbacks.add(callback);
170         }
171     }
172 
unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback)173     public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
174         synchronized (this) {
175             if (mAssistCallbacks != null) {
176                 mAssistCallbacks.remove(callback);
177             }
178         }
179     }
180 
181     // ------------------ Internal API ------------------
182 
183     /**
184      * @hide
185      */
attach(Context context)186     /* package */ final void attach(Context context) {
187         attachBaseContext(context);
188         mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
189     }
190 
dispatchActivityCreated(Activity activity, Bundle savedInstanceState)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 
dispatchActivityStarted(Activity activity)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 
dispatchActivityResumed(Activity activity)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 
dispatchActivityPaused(Activity activity)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 
dispatchActivityStopped(Activity activity)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 
dispatchActivitySaveInstanceState(Activity activity, Bundle outState)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 
dispatchActivityDestroyed(Activity activity)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 
collectComponentCallbacks()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 
collectActivityLifecycleCallbacks()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     }
275 
dispatchOnProvideAssistData(Activity activity, Bundle data)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++) {
286                 ((OnProvideAssistDataListener)callbacks[i]).onProvideAssistData(activity, data);
287             }
288         }
289     }
290 }
291