Application是什么搅吁?
Application和Activity,Service一樣,是Android框架的一個(gè)系統(tǒng)組件,當(dāng)Android程序啟動(dòng)時(shí)系統(tǒng)會(huì)創(chuàng)建一Application 對(duì)象,用來(lái)存儲(chǔ)系統(tǒng)的一些信息骂蓖。
通常我們是不需要指定一個(gè)Application的帆精,這時(shí)系統(tǒng)會(huì)自動(dòng)幫我們創(chuàng)建,如果需要?jiǎng)?chuàng)建自己的Application摹恨,也很簡(jiǎn)單紫岩。
創(chuàng)建一個(gè)類AppApplication繼承Application并在AndroidManifest的application標(biāo)簽中進(jìn)行注冊(cè)(只需要給application 標(biāo)簽增加個(gè)name屬性把自己的Application的名字寫入即可)。
Android系統(tǒng)會(huì)為每個(gè)程序運(yùn)行時(shí)創(chuàng)建一個(gè)Application類的對(duì)象且僅創(chuàng)建一個(gè)
(打開微信安卓系統(tǒng)會(huì)為微信創(chuàng)建一個(gè)Application對(duì)象睬塌,再打開微博安卓系統(tǒng)又會(huì)為微博創(chuàng)建一個(gè)Application對(duì)象)泉蝌,
所以Application可以說(shuō)是單例 (singleton)模式的一個(gè)類.
且Application對(duì)象的生命周期是整個(gè)程序中最長(zhǎng)的,它的生命周期就等于這個(gè)程序的生命周期揩晴。因?yàn)樗侨值膯卫?的勋陪,所以在不同的Activity,Service中獲得的Application對(duì)象都是同一個(gè)對(duì)象。
所以可以通過(guò)Application來(lái)進(jìn)行一些硫兰,數(shù)據(jù)傳遞诅愚,數(shù)據(jù)共享,數(shù)據(jù)緩存等操作。
Application的應(yīng)用
通過(guò)Application傳遞數(shù)據(jù)
假如有一個(gè)Activity A, 跳轉(zhuǎn)到 Activity B ,并需要傳遞一些數(shù)據(jù),通常的作法是Intent.putExtra()讓Intent攜帶违孝,或者有 一個(gè)Bundle把信息加入Bundle讓Intent推薦Bundle對(duì)象刹前,實(shí)現(xiàn)傳遞。但這樣作有一個(gè)問(wèn)題在于雌桑,Intent和Bundle所能攜 帶的數(shù)據(jù)類型都是一些基本的數(shù)據(jù)類型喇喉,如果想實(shí)現(xiàn)復(fù)雜的數(shù)據(jù)傳遞就比較麻煩了,通常需要實(shí)現(xiàn)Serializable或者
Parcellable接口校坑。這其實(shí)是Android的一種IPC數(shù)據(jù)傳遞的方法拣技。如果我們的兩個(gè)Activity在同一個(gè)進(jìn)程當(dāng)中為什么還要
這么麻煩呢,只要把需要傳遞的對(duì)象的引用傳遞過(guò)去就可以了耍目。
基本思路是這樣的膏斤。在Application中創(chuàng)建一個(gè)HashMap ,以字符串為索引邪驮,Object為value這樣我們的HashMap就可 以存儲(chǔ)任何類型的對(duì)象了莫辨。
在Activity A中把需要傳遞的對(duì)象放入這個(gè)HashMap,然后通過(guò)Intent或者其它途經(jīng)再把這索引的字符串傳遞給Activity B ,Activity B 就可以根據(jù)這個(gè)字符串在HashMap中取出這個(gè)對(duì)象了毅访。只要再向下轉(zhuǎn)個(gè)型 沮榜,就實(shí)現(xiàn)對(duì)象的傳遞。
Application數(shù)據(jù)共享
多個(gè)組件之間數(shù)據(jù)共享俺抽。舉例:兩個(gè)Activity之間數(shù)據(jù)共享
Application 對(duì)同一個(gè)應(yīng)用程序是唯一的敞映,所以可以使用Application進(jìn)行數(shù)據(jù)共享。
Application數(shù)據(jù)緩存
在Application中建立兩個(gè)HashMap一個(gè)用于數(shù)據(jù)的傳遞磷斧,一個(gè)用于緩存一些數(shù)據(jù)振愿。
比如有一個(gè)Activity需要從網(wǎng)站獲取一些數(shù)據(jù),獲取完之后我們就可以把這個(gè)數(shù)據(jù)cache到Application當(dāng)中弛饭,
當(dāng)頁(yè)面設(shè)置到其它Activity再回來(lái)的時(shí)候冕末,就可以直接使用緩存好的數(shù)據(jù)了。但如果需要cache一些大量的數(shù)據(jù)侣颂,
最好是cache一些 (軟引用)SoftReference 哭当,并把這些數(shù)據(jù)cache到本地rom上或者sd卡上陌粹。
如果在application中的緩存不存在窄锅,從本地緩存查找明吩,如果本地緩存的數(shù)據(jù)也不存在再?gòu)木W(wǎng)絡(luò)上獲取。
易導(dǎo)致的錯(cuò)誤
使用Application如果保存了一些不該保存的對(duì)象很容易導(dǎo)致內(nèi)存泄漏拒担。
如果在Application的onCreate中執(zhí)行比較耗時(shí)的操作嘹屯,將直接影響程序的啟動(dòng)時(shí)間。
一些清理工作不能依靠onTerminate完成从撼,因?yàn)閍ndroid會(huì)盡量讓你的程序一直運(yùn)行州弟,所以很有可能onTerminate()方法 不會(huì)被調(diào)用。
Application的生命周期
1、onCreate() 程序創(chuàng)建的時(shí)候執(zhí)行
2婆翔、onTerminate() 程序終止的時(shí)候執(zhí)行
在模擬環(huán)境下執(zhí)行拯杠。當(dāng)終止應(yīng)用程序?qū)ο髸r(shí)調(diào)用,不保證一定被調(diào)用啃奴,
當(dāng)程序是被內(nèi)核終止以便為其他應(yīng)用程序釋放資源潭陪,那么將不會(huì)提醒,
并且不調(diào)用應(yīng)用程序Application對(duì)象的onTerminate方法而直接終止進(jìn)程纺腊。
3畔咧、onLowMemory() 低內(nèi)存的時(shí)候執(zhí)行
好的應(yīng)用程序一般會(huì)在這個(gè)方法里面釋放一些不必要的資源來(lái)應(yīng)付當(dāng)后臺(tái)程序已經(jīng)終止茎芭,
前臺(tái)應(yīng)用程序內(nèi)存還不夠時(shí)的情況揖膜。
4、onConfigurationChanged(Configuration newConfig) 配置改變時(shí)觸發(fā)這個(gè)方法梅桩。
5壹粟、onTrimMemory(int level)程序在進(jìn)行內(nèi)存清理時(shí)執(zhí)行
public class MyApp extends Application {
private static final String TAG = "MyApp";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: ");
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG, "onConfigurationChanged: ");
}
@Override
public void onLowMemory() {
super.onLowMemory();
Log.i(TAG, "onLowMemory: ");
}
@Override
public void onTerminate() {
super.onTerminate();
Log.i(TAG, "onTerminate: ");
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
Log.i(TAG, "onTrimMemory: ");
}
}