Application.java revision 7e99bc02c8e2f44dd92d70bfa6e654297e5286d8
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
17package android.app;
18
19import java.util.ArrayList;
20import java.util.List;
21
22import android.content.ComponentCallbacks;
23import android.content.ComponentCallbacks2;
24import android.content.Context;
25import android.content.ContextWrapper;
26import android.content.Intent;
27import android.content.RestrictionEntry;
28import android.content.res.Configuration;
29import android.os.Bundle;
30import android.os.UserManager;
31
32/**
33 * Base class for those who need to maintain global application state. You can
34 * provide your own implementation by specifying its name in your
35 * AndroidManifest.xml's <application> tag, which will cause that class
36 * to be instantiated for you when the process for your application/package is
37 * created.
38 *
39 * <p class="note">There is normally no need to subclass Application.  In
40 * most situation, static singletons can provide the same functionality in a
41 * more modular way.  If your singleton needs a global context (for example
42 * to register broadcast receivers), the function to retrieve it can be
43 * given a {@link android.content.Context} which internally uses
44 * {@link android.content.Context#getApplicationContext() Context.getApplicationContext()}
45 * when first constructing the singleton.</p>
46 */
47public 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<OnProvideAssistData> mAssistCallbacks = null;
53
54    /** @hide */
55    public LoadedApk mLoadedApk;
56
57    public interface ActivityLifecycleCallbacks {
58        void onActivityCreated(Activity activity, Bundle savedInstanceState);
59        void onActivityStarted(Activity activity);
60        void onActivityResumed(Activity activity);
61        void onActivityPaused(Activity activity);
62        void onActivityStopped(Activity activity);
63        void onActivitySaveInstanceState(Activity activity, Bundle outState);
64        void onActivityDestroyed(Activity activity);
65    }
66
67    /**
68     * Callback interface for use with {@link Application#registerOnProvideAssistData}
69     * and {@link Application#unregisterOnProvideAssistData}.
70     */
71    public interface OnProvideAssistData {
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         */
79        public void onProvideAssistData(Activity activity, Bundle data);
80    }
81
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    public void onCreate() {
96    }
97
98    /**
99     * This method is for use in emulated process environments.  It will
100     * never be called on a production Android device, where processes are
101     * removed by simply killing them; no user code (including this callback)
102     * is executed when doing so.
103     */
104    public void onTerminate() {
105    }
106
107    public void onConfigurationChanged(Configuration newConfig) {
108        Object[] callbacks = collectComponentCallbacks();
109        if (callbacks != null) {
110            for (int i=0; i<callbacks.length; i++) {
111                ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
112            }
113        }
114    }
115
116    public void onLowMemory() {
117        Object[] callbacks = collectComponentCallbacks();
118        if (callbacks != null) {
119            for (int i=0; i<callbacks.length; i++) {
120                ((ComponentCallbacks)callbacks[i]).onLowMemory();
121            }
122        }
123    }
124
125    public void onTrimMemory(int level) {
126        Object[] callbacks = collectComponentCallbacks();
127        if (callbacks != null) {
128            for (int i=0; i<callbacks.length; i++) {
129                Object c = callbacks[i];
130                if (c instanceof ComponentCallbacks2) {
131                    ((ComponentCallbacks2)c).onTrimMemory(level);
132                }
133            }
134        }
135    }
136
137    public void registerComponentCallbacks(ComponentCallbacks callback) {
138        synchronized (mComponentCallbacks) {
139            mComponentCallbacks.add(callback);
140        }
141    }
142
143    public void unregisterComponentCallbacks(ComponentCallbacks callback) {
144        synchronized (mComponentCallbacks) {
145            mComponentCallbacks.remove(callback);
146        }
147    }
148
149    public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
150        synchronized (mActivityLifecycleCallbacks) {
151            mActivityLifecycleCallbacks.add(callback);
152        }
153    }
154
155    public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
156        synchronized (mActivityLifecycleCallbacks) {
157            mActivityLifecycleCallbacks.remove(callback);
158        }
159    }
160
161    public void registerOnProvideAssistData(OnProvideAssistData callback) {
162        synchronized (this) {
163            if (mAssistCallbacks == null) {
164                mAssistCallbacks = new ArrayList<OnProvideAssistData>();
165            }
166            mAssistCallbacks.add(callback);
167        }
168    }
169
170    public void unregisterOnProvideAssistData(OnProvideAssistData callback) {
171        synchronized (this) {
172            if (mAssistCallbacks != null) {
173                mAssistCallbacks.remove(callback);
174            }
175        }
176    }
177
178    // ------------------ Internal API ------------------
179
180    /**
181     * @hide
182     */
183    /* package */ final void attach(Context context) {
184        attachBaseContext(context);
185        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
186    }
187
188    /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
189        Object[] callbacks = collectActivityLifecycleCallbacks();
190        if (callbacks != null) {
191            for (int i=0; i<callbacks.length; i++) {
192                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
193                        savedInstanceState);
194            }
195        }
196    }
197
198    /* package */ void dispatchActivityStarted(Activity activity) {
199        Object[] callbacks = collectActivityLifecycleCallbacks();
200        if (callbacks != null) {
201            for (int i=0; i<callbacks.length; i++) {
202                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity);
203            }
204        }
205    }
206
207    /* package */ void dispatchActivityResumed(Activity activity) {
208        Object[] callbacks = collectActivityLifecycleCallbacks();
209        if (callbacks != null) {
210            for (int i=0; i<callbacks.length; i++) {
211                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity);
212            }
213        }
214    }
215
216    /* package */ void dispatchActivityPaused(Activity activity) {
217        Object[] callbacks = collectActivityLifecycleCallbacks();
218        if (callbacks != null) {
219            for (int i=0; i<callbacks.length; i++) {
220                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity);
221            }
222        }
223    }
224
225    /* package */ void dispatchActivityStopped(Activity activity) {
226        Object[] callbacks = collectActivityLifecycleCallbacks();
227        if (callbacks != null) {
228            for (int i=0; i<callbacks.length; i++) {
229                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity);
230            }
231        }
232    }
233
234    /* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) {
235        Object[] callbacks = collectActivityLifecycleCallbacks();
236        if (callbacks != null) {
237            for (int i=0; i<callbacks.length; i++) {
238                ((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity,
239                        outState);
240            }
241        }
242    }
243
244    /* package */ void dispatchActivityDestroyed(Activity activity) {
245        Object[] callbacks = collectActivityLifecycleCallbacks();
246        if (callbacks != null) {
247            for (int i=0; i<callbacks.length; i++) {
248                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity);
249            }
250        }
251    }
252
253    private Object[] collectComponentCallbacks() {
254        Object[] callbacks = null;
255        synchronized (mComponentCallbacks) {
256            if (mComponentCallbacks.size() > 0) {
257                callbacks = mComponentCallbacks.toArray();
258            }
259        }
260        return callbacks;
261    }
262
263    private Object[] collectActivityLifecycleCallbacks() {
264        Object[] callbacks = null;
265        synchronized (mActivityLifecycleCallbacks) {
266            if (mActivityLifecycleCallbacks.size() > 0) {
267                callbacks = mActivityLifecycleCallbacks.toArray();
268            }
269        }
270        return callbacks;
271    }
272
273    /* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) {
274        Object[] callbacks;
275        synchronized (this) {
276            if (mAssistCallbacks == null) {
277                return;
278            }
279            callbacks = mAssistCallbacks.toArray();
280        }
281        if (callbacks != null) {
282            for (int i=0; i<callbacks.length; i++) {
283                ((OnProvideAssistData)callbacks[i]).onProvideAssistData(activity, data);
284            }
285        }
286    }
287}
288