Application
android提供了一个Application类,每当应用程序启动时,系统会自动将这个类进行初始化。在项目中,我们在一些工具类采用了单例模式,其生命周期和整个应用程序相同,并且可能直接或者间接的需要Context引用来进行获取资源的操作。那么我们需要一个全局Context也就是Application。
Android基础之Context文章中我们知道,Application生命周期是整个App
自定义Application用途
- 为得到一个Application对象提供便捷
- 封装一些通用操作
- 初始化一些全局的变量数据
对于前两点,Google官方是不建议这样做的。因为使用一个单例模式同样可以做到。但是自定义Application没有任何副作用。而在Application中的onCreate()方法里去初始化各种全局的变量数据是一种比较推荐的做法。
自定义Application
新建一个Application类
新建一个MyApplication并让它继承自Application
public class MyApplication extends Application{
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
}
public static Context getInstance() {
return mContext;
}
}
在AndroidManifest文件中指定自定义的Application
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" />
指定完成后,当我们的程序启动时Android系统就会创建一个MyApplication的实例,如果这里不指定的话就会默认创建一个Application的实例。
使用自定义Application注意点
初始化数据的时机
我们不能够在自定义的Application类的构造方法里初始化一些需要Context引用操作得到的数据,例如getResources()、getPackageName()、getSystemService()等等。一旦这样做,应用程序已启动就会报控指针的错误。我们应该在onCreate()方法中初始化。
ContextWrapper中有一个attachBaseContext()方法,这个方法会将传入的一个Context参数赋值给mBase对象,之后mBase对象就有值了。而我们又知道,所有Context的方法都是调用这个mBase对象的同名方法,那么也就是说如果在mBase对象还没赋值的情况下就去调用Context中的任何一个方法时,就会出现空指针异常,(引用自 Android Context完全解析,你所不知道的Context的各种细节)
Application方法执行顺序:
自定义Application采用单例模式
Application全局只有一个,它本身就已经是单例了,无需再用单例模式去为它做多重实例保护了。
错误示范:
public class MyApplication extends Application {
private static MyApplication app;
public static MyApplication getInstance() {
if (app == null) {
app = new MyApplication();
}
return app;
}
}
上述代码的getInstance()方法中,如果app == null,采用new来创建一个新的Application,并将其返回。返回的Application对象不具备Context的能力,只是一个普通的Application实例。这和第一个错误类似,Application对象应该由Android系统来创建。
正确的操作:
public class MyApplication extends Application {
private static MyApplication app;
public static MyApplication getInstance() {
return app;
}
@Override
public void onCreate() {
super.onCreate();
app = this;
}
}