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