Android 中的Application

Application和Activity、Service一樣是android框架的一個(gè)系統(tǒng)組件沾瓦,當(dāng)android程序啟動(dòng)時(shí)系統(tǒng)會(huì)創(chuàng)建一個(gè)application對(duì)象,用來存儲(chǔ)系統(tǒng)的一些信息。通常我們是不需要指定一個(gè)Application的贯莺,這時(shí)系統(tǒng)會(huì)自動(dòng)幫我們創(chuàng)建风喇,如果需要?jiǎng)?chuàng)建自己的Application,也很簡(jiǎn)單創(chuàng)建一個(gè)類繼承Application并在manifest的application標(biāo)簽中進(jìn)行注冊(cè)(只需要給Application標(biāo)簽增加個(gè)name屬性把自己的Application的名字定入即可)缕探。

因?yàn)锳pplication是全局的單例的魂莫,所以在不同的Activity、Service中獲得的對(duì)象都是同一個(gè)對(duì)象爹耗。通過Application來進(jìn)行一些耙考,數(shù)據(jù)傳遞,數(shù)據(jù)共享等鲸沮,數(shù)據(jù)緩存等操作琳骡。

Data passing between components using Application

假如有一個(gè)Activity A,跳轉(zhuǎn)到Activity B,并需要推薦一些數(shù)據(jù)讼溺,通常的作法是Intent.putExtra()讓Intent攜帶楣号,或者有一個(gè)Bundle把信息假如Bundle讓Intent推薦Bundle對(duì)象,實(shí)現(xiàn)傳遞怒坯。但這樣做有一個(gè)問題在于炫狱,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)程中為什么還要這么麻煩呢归敬,只要把需要傳遞的對(duì)象的引用傳遞過去就可以了酷含。

基本思路是這樣的,在Application中創(chuàng)建一個(gè)HashMap<String,Object>汪茧,以字符串為索引椅亚,Object為value這樣我們的HashMap就可以存儲(chǔ)任何類型的對(duì)象了。在Activity A中把需要傳遞的對(duì)象放入這個(gè)HashMap舱污,然后通過Intent或者其它途徑再把這個(gè)索引的字符串傳遞給Activity B呀舔,Activity B就可以根據(jù)這個(gè)字符串在HashMap中提取出這個(gè)對(duì)象了。只要再向下轉(zhuǎn)個(gè)型扩灯,就實(shí)現(xiàn)了對(duì)象的傳遞媚赖。

Data caching in Application

我一般習(xí)慣在Application中建立兩個(gè)HashMap一個(gè)用于數(shù)據(jù)的傳遞,一個(gè)用于緩存一些數(shù)據(jù)珠插。
比如有一個(gè)Activity需要從網(wǎng)站獲取一些數(shù)據(jù)惧磺,獲取完之后我們就可以把這個(gè)數(shù)據(jù)cache到Application當(dāng)中,當(dāng)頁面設(shè)置到其它Activity再回來的時(shí)候捻撑,就可以直接使用緩存好的數(shù)據(jù)了豺妓。但如果需要cache一些大量的數(shù)據(jù)惜互,最好是cache一些 (軟引用)SoftReference ,并把這些數(shù)據(jù)cache到本地rom上或者sd卡上琳拭。如果在application中的緩存不存在训堆,從本地緩存查找,如果本地緩存的數(shù)據(jù)也不存在再?gòu)木W(wǎng) 絡(luò)上獲取白嘁。

PitFalls

使用Application如果保存了一些不該保存的對(duì)象很容易導(dǎo)致內(nèi)存泄漏坑鱼。如果在Application中的onCreate中執(zhí)行比較耗時(shí)的操作,將直接影響程序的啟動(dòng)時(shí)間絮缅。這些清理工作不能依靠onTerminate完成鲁沥,因?yàn)閍ndroid會(huì)盡量讓你的程序一直運(yùn)行,所以很可能onTerminate不會(huì)被調(diào)用耕魄。

MemoryLeak
在Java中內(nèi)存泄漏是指画恰,某個(gè)(某些)對(duì)象已經(jīng)不再被使用應(yīng)該被gc所回收,但有一個(gè)對(duì)象持有這個(gè)對(duì)象的引用而阻止這個(gè)對(duì)象被回收吸奴。比如我們通常會(huì)創(chuàng)建一個(gè)View TextView tv = new TextView(this);這里的this通常都是Activity允扇。所以這個(gè)TextView就持有著這個(gè)Activity的引用。

通常情況下则奥,當(dāng)用戶轉(zhuǎn)動(dòng)手機(jī)的時(shí)候考润,android會(huì)重新調(diào)用OnCreate()方法生成一個(gè)新的Activity,原來的 Activity應(yīng)該被GC所回收读处。但如果有個(gè)對(duì)象比如一個(gè)View的作用域超過了這個(gè)Activity(比如有一個(gè)static對(duì)象或者我們把這個(gè) View的引用放到了Application當(dāng)中)糊治,這時(shí)候原來的Activity將不能被GC所回收,Activity本身又持有很多對(duì)象的引用罚舱,所以 整個(gè)Activity的內(nèi)存被泄漏了井辜。
經(jīng)常導(dǎo)致內(nèi)存泄漏的一些原因:
keeping a long-lived reference to a Context.持有一個(gè)context的對(duì)象,從而gc不能回收管闷。

1抑胎,一個(gè)View,的作用域超出了所在的Activity的作用域渐北,比如一個(gè)static的View或者 把一個(gè)View cache到了application當(dāng)中 etc
2,某些與View關(guān)聯(lián)的Drawable的作用域超出了Activity的作用域。
3铭拧,Runnable對(duì)象:比如在一個(gè)Activity中啟用了一個(gè)新線程去執(zhí)行一個(gè)任務(wù)赃蛛,在這期間這個(gè)Activity被系統(tǒng)回收了, 但Runnalbe的任務(wù)還沒有執(zhí)行完畢并持有Activity的引用而泄漏搀菩,但這種泄漏一般來泄漏一段時(shí)間呕臂,只有Runnalbe的線程執(zhí)行完閉,這個(gè) Activity又可以被正撤景希回收了歧蒋。
4,內(nèi)存類的對(duì)象作用域超出Activity的范圍:比如定義了一個(gè)內(nèi)存類來存儲(chǔ)數(shù)據(jù),又把這個(gè)內(nèi)存類的對(duì)象傳給了其它Activity 或者Service等谜洽。因?yàn)閮?nèi)部類的對(duì)象會(huì)持有當(dāng)前類的引用萝映,所以也就持有了Context的引用。解決方法是如果不需要當(dāng)前的引用把內(nèi)部類寫成 static或者阐虚,把內(nèi)部類抽取出來變成一個(gè)單獨(dú)的類序臂,或者把避免內(nèi)部對(duì)象作用域超出Activity的作用域。
out Of Memery Error 在android中每一個(gè)程序所分到的內(nèi)存大小是有限的实束,如果超過了這個(gè)數(shù)就會(huì)報(bào)Out Of Memory Error奥秆。android給程序分配的內(nèi)存大小與手機(jī)硬件有關(guān),以下是一些手機(jī)的數(shù)據(jù):
G1:16M Droid:24 Nexus One:32M Xoom:48Ms
所以盡量把程序中的一些大的數(shù)據(jù)cache到本地文件咸灿。以免內(nèi)存使用量超標(biāo)构订。

Android使用Application
首先需要重寫Application,主要重寫里面的onCreate方法避矢,就是創(chuàng)建的時(shí)候悼瘾,初始化變量的值。然后在整個(gè)應(yīng)用中的各個(gè)文件中就可以對(duì)該變量進(jìn)行操作了谷异。啟動(dòng)Application時(shí)分尸,系統(tǒng)會(huì)創(chuàng)建一個(gè)PID,即進(jìn)程ID歹嘹,所有的Activity就會(huì)在此進(jìn)程上運(yùn)行箩绍。那么我們?cè)贏pplication創(chuàng)建的時(shí)候初始化全局變量,同一個(gè)應(yīng)用的 所有Activity都可以取到這些全局變量的值尺上,換句話說材蛛,我們?cè)谀骋粋€(gè)Activity中改變了這些全局變量的值,那么在同一個(gè)應(yīng)用的其他Activity中值就會(huì)改變怎抛。

步驟:
第一步卑吭,寫一個(gè)全局的單例模式的MyApplication繼承自Application覆蓋onCreate,在這個(gè)方法里面實(shí)例化Application。

第二步马绝,配置全局的Context

<application         
android:name="com.example.utils.myapplication"             
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"         
android:theme="@style/AppTheme" > 
</application> 

第三步豆赏,使用的時(shí)候根據(jù)類的名稱訪問Context

android.app.Application類包含了4個(gè)公開的方法
void onConfigurationChanged(Configuration newConfig)
void onCreate() //這里才是真正的入口點(diǎn)
void onLowMemory()
void onTerminate()

說明:
onCreate();這個(gè)函數(shù)是當(dāng)我們的應(yīng)用開始之時(shí)就被調(diào)用了富稻,比應(yīng)用中的其他對(duì)象創(chuàng)建的早掷邦,這個(gè)實(shí)現(xiàn)盡可能快一點(diǎn),因?yàn)檫@個(gè)時(shí)間直接影響到我們第一個(gè)Activity/service/receiver椭赋。如果你要重寫這個(gè)方法必須調(diào)用super.onCreate().
onTerminate()這個(gè)函數(shù)是模擬一個(gè)過程環(huán)境抚岗,在真機(jī)中永遠(yuǎn)不會(huì)調(diào)用。

public class MyApplication extends Application

在Activity中要引用定義的變量或方法時(shí)哪怔,首先定義一個(gè)對(duì)象

private MyApplication app;
app = (MyApplication)getApplication();//獲取MyApplication對(duì)象

然后就可以利用其方法了宣蔚。

注:只需要調(diào)用Context的getApplicationContext或者Activity的getApplication方法來獲得一個(gè)Application對(duì)象向抢,然后再得到相應(yīng)的成員變量接口。它是代表我們的應(yīng)用程序的類胚委,使用它可以獲得當(dāng)前應(yīng)用的主題和資源文件中的內(nèi)容等挟鸠。


參考
Android全局變量值之ApplicationContext

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市篷扩,隨后出現(xiàn)的幾起案子兄猩,更是在濱河造成了極大的恐慌,老刑警劉巖鉴未,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枢冤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡铜秆,警方通過查閱死者的電腦和手機(jī)淹真,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來连茧,“玉大人核蘸,你說我怎么就攤上這事⌒パ保” “怎么了客扎?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)罚斗。 經(jīng)常有香客問我徙鱼,道長(zhǎng),這世上最難降的妖魔是什么针姿? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任袱吆,我火速辦了婚禮,結(jié)果婚禮上距淫,老公的妹妹穿的比我還像新娘绞绒。我一直安慰自己,他們只是感情好榕暇,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布蓬衡。 她就那樣靜靜地躺著,像睡著了一般彤枢。 火紅的嫁衣襯著肌膚如雪狰晚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天堂污,我揣著相機(jī)與錄音,去河邊找鬼龄砰。 笑死盟猖,一個(gè)胖子當(dāng)著我的面吹牛讨衣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播式镐,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼反镇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了娘汞?” 一聲冷哼從身側(cè)響起歹茶,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎你弦,沒想到半個(gè)月后惊豺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡禽作,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年尸昧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旷偿。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烹俗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萍程,到底是詐尸還是另有隱情幢妄,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布茫负,位于F島的核電站蕉鸳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏朽褪。R本人自食惡果不足惜置吓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缔赠。 院中可真熱鬧衍锚,春花似錦、人聲如沸嗤堰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踢匣。三九已至告匠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間离唬,已是汗流浹背后专。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留输莺,地道東北人戚哎。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓裸诽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親型凳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丈冬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容