Application.java revision 75951d7c86242f150e5d17ac745458996e97cc72
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;
20
21import android.annotation.CallSuper;
22import android.content.ComponentCallbacks;
23import android.content.ComponentCallbacks2;
24import android.content.Context;
25import android.content.ContextWrapper;
26import android.content.Intent;
27import android.content.res.Configuration;
28import 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 */
45public 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 {
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
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         */
77        public void onProvideAssistData(Activity activity, Bundle data);
78    }
79
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
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
104    public void onTerminate() {
105    }
106
107    @CallSuper
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
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
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        }
162    }
163
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
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     */
186    /* package */ final void attach(Context context) {
187        attachBaseContext(context);
188        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
189    }
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    }
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++) {
286                ((OnProvideAssistDataListener)callbacks[i]).onProvideAssistData(activity, data);
287            }
288        }
289    }
290}
291