進行對Android應(yīng)用程序全解析
Android應(yīng)用程序里提供的Eclipse插件使得運行我們的程序非常簡單。選擇Run > Open Run Dialog菜單;你會看到一個對話框,在這個對話框中就像配置J2ME運行環(huán)境一下,配置一個Luncher。
大功告成!點擊run按鈕,Androi模擬器將運行。當模擬器啟動完成你將看到你的程序。到這里我們就完成了!按照正常思路,一定會想,程序入口點在哪里呢?為什么會從這個Activity 啟動呢?
現(xiàn)在用我們自己的最容易理解的方式來表述:這是因為當啟動這個程序的映像文件時,會發(fā)送一個事件對象Intent, 帶有MAIN的行為屬性,而自動生成的代碼及文件, 有一個AndroidManifest.xml會為HelloWorld這個Activity 配置一個事件過濾器,表明實現(xiàn)了MAIN action,LAUNCHER category的入口點行為。請注意其中的幾行:
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- TextView tv = new TextView(this);
- tv.setText("Hello, Android");
- setContentView(tv);
- }
在多數(shù)情況下, 每個Android應(yīng)用程序運行在自己的Linux進程中. 當一個應(yīng)用的某段code需要運行的時候這個進程將會被創(chuàng)建, 直到不再需要該應(yīng)用或系統(tǒng)要為其他的應(yīng)用釋放內(nèi)存的時候才停止.
一個非常重要且少有的特性是, 應(yīng)用進程的存活時間不是由這個應(yīng)用直接控制的. 而是由系統(tǒng)決定的, 系統(tǒng)會根據(jù)每個已知的正在運行的應(yīng)用情況來定奪, 包括, 該應(yīng)用對用戶的重要性和系統(tǒng)全部可用內(nèi)存.
對于開發(fā)人員來講, 了解每個應(yīng)用組件(尤其是, Activity, Service, 和IntentReceiver)對于應(yīng)用進程存活時間的影響是非常重要的. 如果沒有正確使用, 可能會導致應(yīng)用進程在處理重要工作的時候被系統(tǒng)殺掉.
在對應(yīng)用進程生命周期的理解中, 一個典型的錯誤就是當一個IntentReceiver 接收到Intent 之后, 會在自己的onReceiveIntent()方法中開起一個線程。而后return這個方法. 一旦這個方法return, 系統(tǒng)會認為這個IntentReceiver 不在處于活躍狀態(tài), 也就認為他的宿主進程不再需要(除非還包有其他活躍的應(yīng)用組件)。
以至于當系統(tǒng)需要回收內(nèi)存的時候會隨時釋kill掉這個進程, 中止其中的子線程. 解決這個問題的辦法是在IntentReceiver中啟動一個Service, 這樣系統(tǒng)會知道在這個進程中還有活躍的任務(wù)需要完成. 為了決定在內(nèi)存較低的時候殺掉哪個進程, Android應(yīng)用程序會根據(jù)運行在這些進程內(nèi)的組件及他們的狀態(tài)把進程劃分成一個"重要程度層次". 其重要的程度按以下規(guī)則排序:
前端進程可以是一個持有運行在屏幕最前端并與用戶交互的Activity的進程(onResume方法被調(diào)用時),也可以是持有一個正在運行的IntentReceiver(也就是說他正在執(zhí)行自己的onReceiveIntent方法)的進程。
在系統(tǒng)中, 只會有少數(shù)這樣的進程, 并且除非內(nèi)存已經(jīng)低到不夠這些進程運行, 否則系統(tǒng)不會主動殺掉這些進程. 這時, 設(shè)備通常已經(jīng)達到了需要內(nèi)存整理的狀態(tài), 所以殺掉這些進程是為了不讓用戶界面停止響應(yīng)。