1. 简介
对于Android应用程序,默认情况下,系统会生成一个Application对象,除非你进行了自定义Application类,并且在清单文件中指定了“android:name”属性为该自定义类的类名称。
例如:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.test.myapp"
......
<application android:icon="@drawable/icon"
android:allowBackup="false"
android:name=".core.MyApp"
android:debuggable="false"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light"
tools:ignore="HardcodedDebugMode">
<activity android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize|navigation|keyboard"
android:excludeFromRecents="true"
android:exported="true"
android:finishOnTaskLaunch="false"
android:launchMode="singleInstance"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2自定义Application的好处:
(1)可扩展;
(2)因为一个应用程序只有一个Application对象(或者其派生类对象),所以,可以作为全局对象来使用。可以在这个类中,进行全局数据的存储或全局函数的设置。例如,数据传递,数据共享 等,数据缓存等操作。
(3)作为单例模式,可以在任何其它组件或者模块中进行获取或者引用,避免了“有时候,Activity作为参数,在其它模块或组件销毁时无法即使销毁”的问题。例如:
当用户转动手机的时候,android会重新调用OnCreate()方法生成一个新的Activity,原来的 Activity应该被GC所回收。但如果有个对象比如一个View的作用域超过了这个Activity(比如有一个static对象或者我们把这个 View的引用放到了Application当中),这时候原来的Activity将不能被GC所回收,Activity本身又持有很多对象的引用,所以 整个Activity的内存被泄漏了。
(4)Application也有自己的生命周期,自定义的Application,可以重载Application中的响应的方法,从而实现一些诸如“在程序结束运行时,需要数据清除”等功能。增加程序的健壮性。
3. 自定义Application的举例:
(1)例1:
public class MmsApp extends Application {
@Override
public void onCreate() {
super.onCreate();
initDb()
}
public void initDb() {
//your code
}
};
(2)例2:单例模式:
public class MyApp extends Application {
private static MyApp mInstance = null;
@Override
public void onCreate() {
super.onCreate();
getInstance()
}
public static MyApp getInstance(){
synchronized (MyApp.class){
if (mInstance==null){
synchronized (MyApp.class){
return new MyApp();
}
}
}
return mInstance;
}
}
说明:
mInstance是一个私有成员,通过getInstance来进行获取。典型的单例模式。
4. Application源码之观察者模式:
Application类中定义了registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback)方法,可以监听activity的生命周期,所以我们可以直接在application中管理activity。
代码如下:
public class MyApplication extends Application {
//activity列表
private static List<Activity> myActivitys = new ArrayList<>();
private static Activity topActivity;
@Override
public void onCreate() {
super.onCreate();
registerActivityListener();
}
/**
* 注册监听activity的创建和销毁
*/
private void registerActivityListener() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
//activity创建
addActivity(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
topActivity = activity;
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
//activity销毁
removeActivity(activity);
}
});
}
/**
* 添加activity到列表
*
* @param activity 添加的activity
*/
public void addActivity(Activity activity) {
if (myActivitys == null)
return;
myActivitys.add(activity);
}
/**
* 从列表移除指定activity
*
* @param activity 移除的activity
*/
public void removeActivity(Activity activity) {
if (myActivitys == null || myActivitys.isEmpty())
return;
myActivitys.remove(activity);
}
/**
* 根据类名从列表获取activity
*
* @param className 类名
* @return 指定activity,没有则返回 null
*/
public static Activity getActivity(String className) {
Activity myActivity = null;
if (myActivitys != null) {
for (Activity activity : myActivitys)
if (activity.getClass().getName().equals(className))
myActivity = activity;
}
return myActivity;
}
/**
* 销毁指定activity
*
* @param activity 销毁的activity
*/
public static void finishActivity(Activity activity) {
if (myActivitys == null || myActivitys.isEmpty())
return;
if (activity != null) {
myActivitys.remove(activity);
activity.finish();
}
}
/**
* 销毁所有activity
*/
public static void finishAllActivity() {
if (myActivitys == null || myActivitys.isEmpty())
return;
for (Activity activity : myActivitys)
activity.finish();
myActivitys.clear();
}
/**
* 应用在前台时,当前页面
* @return
*/
public static Activity getTopActivity(){
return topActivity;
}
}
说明:
(1)ActivityLifecycleCallbacks是Application类中的一个接口,这些接口中声明的方法对应于Activity的生命周期中的方法:
//Application.java中的源码
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
(2)Application中,使用观察者模式进行Activity的一些状态或生命周期的管理。当横竖屏切换时,当内存不够用时。我们通过分析源码可以看到这种模式:
首先,添加观察者与删除观察者:
public void registerComponentCallbacks(
ComponentCallbacks callback) {
synchronized (mComponentCallbacks) {
mComponentCallbacks.add(callback);
}
}
public void unregisterComponentCallbacks(
ComponentCallbacks callback) {
synchronized (mComponentCallbacks) {
mComponentCallbacks.remove(callback);
}
}
其次,观察者的调用:
当横竖屏切换时,onConfigurationChanged会被调用。而在onConfigurationChanged中,会通过mComponentCallbacks来对各个组件的onConfigurationChanged进行调用。
public void onConfigurationChanged(Configuration newConfig) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
}
}
}
其中,ComponentCallbacks就是观察者,而这个观察者,对应的最终是Activity,Service这些组件。所以,最终调用到这些组件的onConfigurationChanged方法中。源码序列图如下:
其中,registerComponentCallbacks的实现已经在前面说过了。
同理,在Application中,各个生命周期也是这样管理的,参考如下源代码:
public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.add(callback);
}
}
void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
savedInstanceState);
}
}
}