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