Preface
在學習一個SDK的時候,遇到了Application
類的相關知識,其實之前也有學習過Application
類的一些知識,但是日常開發中使用頻率不高,忘得差不多了.現在重新來總結下Application
的使用
英語基礎好的可以去參考官方文件
下面是官網對Application類的簡介
Base class for maintaining global application state. You can provide your own implementation by creating a subclass and specifying the fully-qualified name of this subclass as the "android:name"
attribute in your AndroidManifest.xml's <application>
tag. The Application class, or your subclass of the Application class, is instantiated before any other class when the process for your application/package is created.
大概意思就是Application是用來維護全域性應用狀態的基類.可以通過自己建立子類並且在Manifest.xml
檔案中通過name
屬性來標記,用來實現自定義的功能.Application類將會在任何類之前例項化
繼承關係
Application
類繼承自ContextWarpper
類
下面是示意圖
特點
-
單例模式:每個App都有且只有一個Application的例項物件(多程式APP除外),可以通過繼承Application子類來進行自定義,如果沒有自定義的話,APP會在開啟是自動建立一個預設的例項物件.
-
生命週期:APP開啟時就會開始例項化Application物件,Application例項的生命週期是最長的,擁有和APP一樣長的生命週期
-
獲取方式:如果沒有自定義Application的話,同樣可以獲取到Application物件,使用
Activity.getApplication()
或者Context.getApplicationContext()
方法都可以獲取到物件.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//這兩種方法都可以獲取到例項物件
val application = application
val otherApplication = applicationContext
}
複製程式碼
- 全域性例項:在不同的元件中(如:Activity,Service),都可以獲取Application物件,並且都會是同一個物件
方法介紹
onCreate()
-
呼叫時間:
當應用開啟時,建立應用程式時呼叫此方法.
Tip:這不是Activity的onCreate(),預設是空實現.
-
使用方式:
可以用來初始化資料一些全域性變數,物件,也可以用來做一些環境的配置.
-
演示:
class MyApplication: Application() {
var whatever = "Whatever"
override fun onCreate() {
super.onCreate()
whatever = "Hello"
//Do something...
}
}
複製程式碼
註冊ComponentCallback2
-
簡單說明:
上面的示意圖中其實還顯示了,Application類是實現了ComponentCallback2介面的,這個介面裡面有三個可以覆寫的方法,可以通過
registerComponentCallbacks()
方法來進行註冊,也可以使用unregisterComponentCallbacks()
來登出. -
使用:
override fun onCreate() {
super.onCreate()
registerComponentCallbacks(object : ComponentCallbacks2 {
override fun onLowMemory() {
}
override fun onConfigurationChanged(newConfig: Configuration?) {
}
override fun onTrimMemory(level: Int) {
}
})
}
複製程式碼
onLowMemory()
這是上面ComponentCallback2
介面中的方法,用於在Android4.0之前的記憶體檢測,開發者可以在這個回撥方法中做一些優化,防止被系統殺程式.目前用這個方法的情景並不多見,除非開發者想向下相容的比較深.目前可以用onTrimMemory()
替代
- 呼叫時間:監聽到系統記憶體很低的時刻
registerComponentCallbacks(object : ComponentCallbacks2 {
override fun onLowMemory() {
//Do something...
}
})
複製程式碼
onTrimMemoey()
這個方法目前用來替代上面的onLowMemory()
方法.方法會傳入一個level的Int引數,這是一個目前系統通知給App的一個記憶體不足等級,越高越嚴重.不同的等級系統會對App做出不同的操作.
記憶體不足級別 | 意義 |
---|---|
TRIM_MEMORY_RUNNING_MODERATE | 等級5:應用可以正常在前臺執行,但是系統已經要開始殺後臺程式了 |
TRIM_MEMORY_RUNNING_LOW | 等級10:應用可以正常在前臺執行,但是系統通知釋放資源,不然會影響速度 |
TRIM_MEMORY_RUNNING_CRITICAL | 等級15:前臺執行,但是大部分後臺被殺死,此時必須釋放記憶體,不然此應用程式也會被殺死 |
TRIM_MEMORY_UI_HIDDEN | 等級20:系統會將該應用的UI資源收回,轉為後臺 |
TRIM_MEMORY_BACKGROUND | 等級40:此時應用處於LRU快取列表的最近位置,需要立刻釋放容易恢復的資源 |
TRIM_MEMORY_MODERATE | 等級60:此時應用處於LRU快取列表的中間位置,有被殺死程式的危險 |
TRIM_MEMORY_COMPLETE | 等級80:非常危險的等級,應用處於快取列表最邊緣,即將被殺死 |
-
系統殺程式規則:
系統會按照LRU Cache列表由低到高殺程式,會優先殺佔用記憶體較高的應用,也就是應用佔用記憶體較小的話,被殺死的概率會降低.
-
使用方法:
override fun onTrimMemory(level: Int) {
if (level in TRIM_MEMORY_RUNNING_MODERATE..(TRIM_MEMORY_RUNNING_LOW - 1)){
//Do something...
}else if (level >= TRIM_MEMORY_RUNNING_LOW){
//Do something...
}
}
複製程式碼
onConfigurationChanged()
-
作用:
監聽APP的一些配置資訊的改變事件(比如螢幕旋轉)
-
呼叫時間:
當配置資訊改變的時候會回撥此方法
-
配置資訊:
配置資訊也就是
Manifest.xml
檔案中Activity
中android:configChanges
屬性的值,在該屬性中填入android:configChanges="keyboardHidden|orientation|screenSize"
可以讓螢幕旋轉時不重啟,而是執行onConfigurationChanged()
方法 -
使用方法:
registerComponentCallbacks(object : ComponentCallbacks2 {
override fun onConfigurationChanged(newConfig: Configuration?) {
//Do something
}
}
複製程式碼
ActivityLifecycleCallbacks()
這是一個介面,可以通過registerActivityLifecycleCallbacks()
和unregisterActivityLifecycleCallbacks()
來註冊/登出對所有Activity生命週期的監聽,當Activity的生命週期發生改變的時候,就會呼叫介面裡的方法.
- 使用方法
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity?) {
}
override fun onActivityResumed(activity: Activity?) {
}
override fun onActivityStarted(activity: Activity?) {
}
override fun onActivityDestroyed(activity: Activity?) {
}
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
}
override fun onActivityStopped(activity: Activity?) {
}
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
}
})
複製程式碼
這個主要就是對不同的生命週期進行監聽,這裡就不往裡面寫操作程式碼了.有興趣的可以自己在裡面加Log測試.
onTerminate()
在程式結束的時候會呼叫,只是用於模擬機的測試,真機上不會呼叫,沒什麼好說的.
registerOnProvideAssistDataListener()&unregisterOnProvideAssistDataListener()
這兩個方法看名字是需要可以註冊準備語音助手的資料的監聽器,需要傳入OnProvideAssistDataListener
介面物件,介面裡只有一個onProvideAssistData(Activity activity,Bundle data)的方法,看官網的介紹是當使用者啟動語音助手時會構建一個Intent.ACTION_ASSIST.而且會附加使用者請求幫助時的使用者位置資訊和上下文.
看網上的說法是國外的手機呼叫語音助手是會呼叫這個方法,我猜測應該不是國外手機,而是谷歌的語音助手,我用OxygenOS系統測試了一下,發現確實在撥出谷歌助手的時候呼叫了方法,Bundle不是空的,但是我也沒找到裡面的資訊,應該是我的方法不對,我目前還沒探究出這個方法要怎麼用.如果有知道的大牛麻煩指導一下
- 我的測試:
registerOnProvideAssistDataListener { activity, data ->
if (data == null) {
Log.d("日誌", "Bundle為空")
} else {
var string = "Bundle{"
for (item in data.keySet()) {
string += " $item => ${data.get(item)};"
}
string += "}Bundle"
Log.d("日誌",string)
Log.d("日誌","data is:$ACTION_ASSIST + $EXTRA_ASSIST_PACKAGE + $EXTRA_ASSIST_CONTEXT")
startActivity(object :Intent(ACTION_ASSIST){})
}
}
複製程式碼
- 測試結果:
日誌: Bundle{}Bundle
日誌: data is:android.intent.action.ASSIST + android.intent.extra.ASSIST_PACKAGE + android.intent.extra.ASSIST_CONTEXT
複製程式碼
自定義Application
介紹完上面的方法,現在總算要開始自定義Application
類了,其實自定義Application類步驟並不多,下面來介紹一下.
-
建立繼承自Application類的子類
這個就沒什麼說的了,直接看程式碼吧
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
//DO something...
}
}
複製程式碼
- 進入Manifest配置自定義類
<application
android:name=".MyApplication"
</application>
複製程式碼
-
獲取Application類的例項
獲取例項的方法上面已經講到了,這裡就不贅述了.
作用
一般來說是不需要自定義Application類的,但是如果需要實現下面的功能,可以自定義Application類
- 初始化部分資源(全域性物件,全域性共享變數,方法等)
- 對記憶體佔用進行優化
- 監聽APP配置資訊和所有Activity的生命週期