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