Android應用程序是用java語(yǔ)言寫(xiě)的,通過(guò)aapt工具把應用程序所需要的任何數據、資源文件打包成apk文件,這個(gè)文件是一個(gè)將應用安裝到手機上的一個(gè)載體。
有很多方式,每個(gè)android應用程序存在于不同的世界:
(1) 默認的,每個(gè)應用在他自己的Linux進(jìn)程中運行,當應用中的任何代碼需要執行時(shí)android就啟動(dòng)相應的進(jìn)程,當不需要執行時(shí)并且系統資源被其他應用請求時(shí)android就關(guān)閉相應的進(jìn)程。
(2) 每個(gè)進(jìn)程都有他自己的虛擬機對象(VM),所以應用程序代碼與其他的應用運行是彼此隔離的。
(3) 默認的,每個(gè)應用被分配一個(gè)唯一的Linux user ID,都被設置權限以便應用程序的文件只對用戶(hù)可見(jiàn)或者只對應用自己可見(jiàn)。
安排兩個(gè)應用程序共享一個(gè)user ID是可能的,這種情況下他們彼此之間是可以看見(jiàn)對方的文件的,為了保護系統資源,擁有相同ID的應用也能被安排運行在一個(gè)相同的Linux進(jìn)程中,共享相同的VM。
1、 應用組件(Application Components)
Android一個(gè)核心的特點(diǎn)就是一個(gè)應用能使用另一個(gè)應用的元素(如果另一個(gè)應用允許的話(huà)),你的應用不需要包含你用到的另一個(gè)應用的代碼也不需要你連接這些代碼,相反的,只是當應用需要這些代碼時(shí),就啟動(dòng)另一個(gè)應用相應的代碼(不是讓另一個(gè)應用全部啟動(dòng))
為了這個(gè)能工作,當一個(gè)應用的任何部分被需要時(shí)系統必須能啟動(dòng)這個(gè)應用進(jìn)程,并且將這個(gè)部分實(shí)例化成java對象,因此,和其他大多數系統不同的是,android應用程序沒(méi)有一個(gè)單獨的程序入口(例如:沒(méi)有main()函數),相反的,android應用有必要的組件以便當需要時(shí)系統能實(shí)例化并運行它,android中有四種組件:
(1) Activity
一個(gè)Activity是一個(gè)可見(jiàn)的用戶(hù)可以使用的用戶(hù)界面,如果一個(gè)應用中有多個(gè)Activity,雖然彼此結合形成一個(gè)應用在一起工作,但是每個(gè)Activity是彼此獨立的,每個(gè)都是Activity的一個(gè)子類(lèi)。
一個(gè)應用程序可能由一個(gè)或多個(gè)Activity組成,這些Activity這么樣顯示,需要多少個(gè)Activity,依賴(lài)于這個(gè)應用的設計者,一般的,有一個(gè)Activity應該被標記成當這個(gè)應用啟動(dòng)時(shí)第一個(gè)呈現出來(lái)給用戶(hù)的。
每個(gè)Activity默認的被給予一個(gè)窗口來(lái)繪制,一般的,這個(gè)窗口占滿(mǎn)整個(gè)屏幕,但是他可以比屏幕小并且浮在另一個(gè)窗口的上面。
一個(gè)窗口中的可見(jiàn)的內容是由一些具有層次關(guān)系的view組成的,都是繼承自View類(lèi)的,每個(gè)view都控制一個(gè)窗口中的特定的矩形框,parent view 包含children view和組織children view的布局,leaf view(那些在繼承層次最底層的view)繪制在他們所控制的矩形框中,并且對用戶(hù)的動(dòng)作做出直接的回應,因此view就是Activity和用戶(hù)交互的地方,android有很多已經(jīng)做好的view你可以使用,包括buttons,text fields,scroll bars,menu items,check boxes等等
一個(gè)view hierarchy是通過(guò)Activity.setContentView()方法被放到一個(gè)Activity的window中的,content view是view hierarchy中最頂端的那個(gè)view。
(2) Services
一個(gè)service不是一個(gè)用戶(hù)可見(jiàn)的組件,在不確定的一段時(shí)間內運行在后臺,每個(gè)service都繼承自Service類(lèi)。
你可以連接(connect)或者綁定(bind)到一個(gè)正在運行的service(如果這個(gè)service還沒(méi)運行的話(huà)就啟動(dòng)它),當連接到service后,你可以通過(guò)一個(gè)service暴露出來(lái)的接口和這個(gè)service交流,對music service來(lái)說(shuō),這個(gè)接口可以是允許用戶(hù)暫停,后退,停止,重新播放。
和Activity或者其他組件一樣,service運行在這個(gè)應用進(jìn)程的主線(xiàn)程中,所以他不會(huì )阻塞其他的組件或者用戶(hù)界面,他們經(jīng)常為那些耗時(shí)長(cháng)的任務(wù)單獨開(kāi)一個(gè)線(xiàn)程。
(3) Broadcast receivers
一個(gè)broadcast receiver這樣一個(gè)組件,他只是接收廣播并作出反應,在系統中有很多已有的廣播,比如反應時(shí)區變化(timezone)的,電池變化(battery)的,用戶(hù)修改了系統語(yǔ)言時(shí)的廣播,應用程序也可以自己定義廣播,比如定義這樣一個(gè)廣播,讓其他的應用知道某些數據已經(jīng)下載完畢了可以使用了。
一個(gè)應用可以有任意多個(gè)broadcast receiver來(lái)對他所關(guān)心的廣播進(jìn)行監聽(tīng)并作出反應。所有的receiver都繼承自BroadcastReceiver類(lèi)。
BroadcastReceiver不顯示在用戶(hù)界面上,然而,他們可以啟動(dòng)一個(gè)Activity來(lái)作為他們接收到的信息一種反應,或者他們可以使用NotificationManager來(lái)提示用戶(hù),Notifications可以通過(guò)不同的方式獲得用戶(hù)的注意,比如點(diǎn)亮呼吸燈,震動(dòng)電話(huà),播放一個(gè)聲音等等,他們一般放一個(gè)圖標在狀態(tài)欄上,來(lái)讓用戶(hù)可以打開(kāi)獲得這些信息。
(4) Content providers
Content providers是一個(gè)應用程序數據的集合,來(lái)讓其他的應用可以訪(fǎng)問(wèn)這些數據,這些數據可以被存在文件系統中,SQLite數據庫中,或者其他可以存數據的地方,Content providers是一個(gè)基本的方法集合來(lái)使其他的應用可以獲得和存儲這些數據,然而應用不直接調用這些方法,而是使用一個(gè)ContentResolver對象來(lái)調用這些方法,一個(gè)ContentResolver可以和任何的Content providers交流,他和provider協(xié)作來(lái)管理系統中任何進(jìn)程間的通信。
無(wú)論何時(shí)一個(gè)請求都應該由一個(gè)特定的組件來(lái)處理,android系統來(lái)確保包含這個(gè)組件的應用進(jìn)程運行,如果需要就啟動(dòng)它,如果需要就為這個(gè)組件創(chuàng )造一個(gè)實(shí)例,確保這個(gè)組件的一個(gè)適當的實(shí)例可以被得到。
2、 啟動(dòng)組件:intent
當有一個(gè)來(lái)自于content resolver的請求指向Content provider時(shí),content provider啟動(dòng),其他的三個(gè)組件(Activity,service,broadcast receiver)是通過(guò)一個(gè)叫做intent的異步的消息來(lái)啟動(dòng)的,一個(gè)intent持有一個(gè)message的內容,對Activity和service來(lái)說(shuō),他是一個(gè)被要求的動(dòng)作(action)和在該動(dòng)作上的數據的URI,對broadcast receiver來(lái)說(shuō),intent對象是一個(gè)被廣播的動(dòng)作。
針對每種組件分別有對應的方法來(lái)啟動(dòng)它:
(1) 一個(gè)Activity是通過(guò)傳遞一個(gè)Intent對象到Context.startActivity()或者Activity.startActivityForResult()來(lái)啟動(dòng)的(或者去做一些新的任務(wù)),被啟動(dòng)的這個(gè)Activity可以通過(guò)getIntent()來(lái)獲得導致他啟動(dòng)的那個(gè)intent的。
(2) 一個(gè)service是通過(guò)傳遞一個(gè)Intent對象到Context.startService()來(lái)啟動(dòng)的(或者給一些新的命令給正在運行的service),android調用service的onStart()方法,并且把Intent對象傳遞給他,同樣的,一個(gè)Intent可以傳遞到Context.bindService()方法里來(lái)建立一個(gè)介于正在運行的service和調用他的組件之間的連接,這個(gè)service通過(guò)onBind()方法來(lái)接收這個(gè)Intent對象,(如果這個(gè)service還沒(méi)有運行,bindservice()能選擇性的啟動(dòng)它),在后面的部分,關(guān)于綁定service的更多詳細的信息請查看遠程調用。
(3) 一個(gè)應用可以通過(guò)傳遞一個(gè)Intent對象給像Context.sendBroadcast(), Context.sendOrderedBroadcast(), Context.sendStickyBroadcast()這樣的方法來(lái)開(kāi)始一個(gè)廣播,android通過(guò)調用對應的onReceive()方法將intent傳遞給所有對這個(gè)廣播感興趣的broadcast receiver。
3、 關(guān)閉組件(Shutting down components)
當對來(lái)自于content resolver的請求作出回應時(shí)content provider就啟動(dòng)了,當有一個(gè)感興趣的broadcast message被廣播時(shí),broadcast receiver啟動(dòng),所以我們需要知道怎么關(guān)閉這些組件。
(1) Activity可以通過(guò)調用它自己的finish()方法來(lái)關(guān)閉,一個(gè)Activity也可以通過(guò)調用finishActivity()來(lái)關(guān)閉另一個(gè)Activity(這個(gè)Activity是通過(guò)調用startActivityForResult()來(lái)啟動(dòng)的)。
(2) 一個(gè)service可以通過(guò)調用自己的stopSelf(),或者Context.stopService()來(lái)關(guān)閉。
當組件不再使用時(shí)或者android為了更多組件能運行而回收內存時(shí),android系統是關(guān)閉這些組件的,在后面的部分,可以在組件的生命周期中看到更多更詳細的介紹。
4、 Activities and Tasks
一個(gè)Activity可以啟動(dòng)另一個(gè)Activity,即使這個(gè)Activity是定義在另一個(gè)應用里的,比如說(shuō),你想展示給用戶(hù)一條街的地圖,現在已經(jīng)有一個(gè)Activity可以做這件事,那么現在你需要做的就是將你請求的信息放進(jìn)一個(gè)Intent對象里,并且通過(guò)startActivity()傳遞給他,這個(gè)地圖就可以顯示出來(lái)了,但用戶(hù)按下BACK鍵時(shí),你的Activity又重新出現在屏幕上。
對用戶(hù)來(lái)說(shuō),顯示地圖的Activity和你的Activity好像在一個(gè)應用中的,即使是他們是定義在不用的應用中的,運行在各自的應用進(jìn)程中,android將兩個(gè)Activity放進(jìn)一個(gè)task里,一個(gè)task是一組彼此聯(lián)系的Activity,被安排在一個(gè)堆棧中,堆棧中的根Activity就是開(kāi)辟這個(gè)task的,一般的,他是用戶(hù)選擇應用后首先啟動(dòng)的那個(gè)Activity,堆棧頂部的Activity是當前正在運行的Activity,當一個(gè)Activity啟動(dòng)另一個(gè)Activity時(shí),新的Activity被壓進(jìn)堆棧中,成為運行的Activity,當用戶(hù)按下BACK鍵,當前的Activity彈出堆棧,先前的Activity恢復成為運行的Activity。
一個(gè)task就是一組Activity的堆棧,不是在manifest文件里的一個(gè)類(lèi),一個(gè)元素,所以沒(méi)有方法來(lái)為一個(gè)task里的Activity獨立的設置值,對task設置值是在root Activity里設置的。
一個(gè)task里的所有Activity組成一個(gè)單元,整個(gè)task(整個(gè)Activity堆棧)可以在前臺,也可以在后臺(應用程序的切換就是task的前后臺的切換),假設,當前的task有四個(gè)Activity在堆棧里,用戶(hù)按下HOME鍵,去開(kāi)啟另一個(gè)應用(實(shí)際上是一個(gè)新的task),那么當前的task就退到后臺運行,新開(kāi)啟的應用的root Activity此時(shí)就顯示出來(lái)了,然后,過(guò)了一段時(shí)間,用戶(hù)回到主界面,又重新選擇了以前的那個(gè)應用(先前的那個(gè)task),那么先前的那個(gè)task此時(shí)又回到了前臺了,當用戶(hù)按下BACK鍵時(shí),屏幕不是顯示剛剛關(guān)閉的那個(gè)應用,而是移除回到前臺的這個(gè)task堆棧棧頂Activity,將下一個(gè)Activity顯示出來(lái)。
文章來(lái)源于領(lǐng)測軟件測試網(wǎng) http://kjueaiud.com/