Application
Android提供了一個(gè)Application類(lèi),每當(dāng)應(yīng)用程序啟動(dòng)時(shí)炎码,系統(tǒng)會(huì)自動(dòng)將這個(gè)類(lèi)進(jìn)行初始化秋泳。在項(xiàng)目中,我們?cè)谝恍┕ぞ哳?lèi)采用了單例模式矫钓,其生命周期和整個(gè)應(yīng)用程序相同舍杜,并且可能直接或者間接的需要Context引用來(lái)進(jìn)行獲取資源的操作。那么我們需要一個(gè)全局Context也就是Application既绩。
Android基礎(chǔ)之Context文章中我們知道,Application生命周期是整個(gè)App
自定義Application用途
- 為得到一個(gè)Application對(duì)象提供便捷
- 封裝一些通用操作
- 初始化一些全局的變量數(shù)據(jù)
對(duì)于前兩點(diǎn)私杜,Google官方是不建議這樣做的。因?yàn)槭褂靡粋€(gè)單例模式同樣可以做到锣光。但是自定義Application沒(méi)有任何副作用铝耻。而在Application中的onCreate()方法里去初始化各種全局的變量數(shù)據(jù)是一種比較推薦的做法。
自定義Application
新建一個(gè)Application類(lèi)
新建一個(gè)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" />
指定完成后频丘,當(dāng)我們的程序啟動(dòng)時(shí)Android系統(tǒng)就會(huì)創(chuàng)建一個(gè)MyApplication的實(shí)例泡态,如果這里不指定的話(huà)就會(huì)默認(rèn)創(chuàng)建一個(gè)Application的實(shí)例。
使用自定義Application注意點(diǎn)
初始化數(shù)據(jù)的時(shí)機(jī)
我們不能夠在自定義的Application類(lèi)的構(gòu)造方法里初始化一些需要Context引用操作得到的數(shù)據(jù)某弦,例如getResources()、getPackageName()怔毛、getSystemService()等等亮钦。一旦這樣做充活,應(yīng)用程序已啟動(dòng)就會(huì)報(bào)控指針的錯(cuò)誤。我們應(yīng)該在onCreate()方法中初始化混卵。
ContextWrapper中有一個(gè)attachBaseContext()方法,這個(gè)方法會(huì)將傳入的一個(gè)Context參數(shù)賦值給mBase對(duì)象蚁滋,之后mBase對(duì)象就有值了赘淮。而我們又知道,所有Context的方法都是調(diào)用這個(gè)mBase對(duì)象的同名方法梢卸,那么也就是說(shuō)如果在mBase對(duì)象還沒(méi)賦值的情況下就去調(diào)用Context中的任何一個(gè)方法時(shí)蛤高,就會(huì)出現(xiàn)空指針異常蚣旱,(引用自 Android Context完全解析,你所不知道的Context的各種細(xì)節(jié))
Application方法執(zhí)行順序:
自定義Application采用單例模式
Application全局只有一個(gè)沟涨,它本身就已經(jīng)是單例了异吻,無(wú)需再用單例模式去為它做多重實(shí)例保護(hù)了。
錯(cuò)誤示范:
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來(lái)創(chuàng)建一個(gè)新的Application酵颁,并將其返回月帝。返回的Application對(duì)象不具備Context的能力嚷辅,只是一個(gè)普通的Application實(shí)例簸搞。這和第一個(gè)錯(cuò)誤類(lèi)似趁俊,Application對(duì)象應(yīng)該由Android系統(tǒng)來(lái)創(chuàng)建寺擂。
正確的操作:
public class MyApplication extends Application {
private static MyApplication app;
public static MyApplication getInstance() {
return app;
}
@Override
public void onCreate() {
super.onCreate();
app = this;
}
}