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