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;
}
}