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.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 {
     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