當(dāng)按下Android設(shè)備電源鍵時(shí)究竟發(fā)生了什么?
創(chuàng)新互聯(lián)于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站建設(shè)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元新鄉(xiāng)做網(wǎng)站,已為上家服務(wù),為新鄉(xiāng)各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108
Android的啟動(dòng)過(guò)程是怎么樣的?
什么是Linux內(nèi)核?
桌面系統(tǒng)linux內(nèi)核與Android系統(tǒng)linux內(nèi)核有什么區(qū)別?
什么是引導(dǎo)裝載程序?
什么是Zygote?
什么是X86以及ARM linux?
什么是init.rc?
什么是系統(tǒng)服務(wù)?
當(dāng)我們想到Android啟動(dòng)過(guò)程時(shí),腦海中總是冒出很多疑問(wèn)。本文將介紹Android的啟動(dòng)過(guò)程,希望能幫助你找到上面這些問(wèn)題的答案。
Android是一個(gè)基于Linux的開(kāi)源操作系統(tǒng)。x86(x86是一系列的基于intel 8086 CPU的計(jì)算機(jī)微處理器指令集架構(gòu))是linux內(nèi)核部署最常見(jiàn)的系統(tǒng)。然而,所有的Android設(shè)備都是運(yùn)行在ARM處理器(ARM 源自進(jìn)階精簡(jiǎn)指令集機(jī)器,源自ARM架構(gòu))上,除了英特爾的Xolo設(shè)備()。Xolo來(lái)源自凌動(dòng)1.6GHz x86處理器。Android設(shè)備或者嵌入設(shè)備或者基于linux的ARM設(shè)備的啟動(dòng)過(guò)程與桌面版本相比稍微有些差別。這篇文章中,我將解釋Android設(shè)備的啟動(dòng)過(guò)程。深入linux啟動(dòng)過(guò)程是一篇講桌面linux啟動(dòng)過(guò)程的好文。
當(dāng)你按下電源開(kāi)關(guān)后Android設(shè)備執(zhí)行了以下步驟。
此處圖片中step2中的一個(gè)單詞拼寫錯(cuò)了,Boot Loaeder應(yīng)該為Boot Loader(多謝@jameslast 提醒)
第一步:?jiǎn)?dòng)電源以及系統(tǒng)啟動(dòng)
當(dāng)電源按下,引導(dǎo)芯片代碼開(kāi)始從預(yù)定義的地方(固化在ROM)開(kāi)始執(zhí)行。加載引導(dǎo)程序到RAM,然后執(zhí)行。
第二步:引導(dǎo)程序
引導(dǎo)程序是在Android操作系統(tǒng)開(kāi)始運(yùn)行前的一個(gè)小程序。引導(dǎo)程序是運(yùn)行的第一個(gè)程序,因此它是針對(duì)特定的主板與芯片的。設(shè)備制造商要么使用很受歡迎的引導(dǎo)程序比如redboot、uboot、qi bootloader或者開(kāi)發(fā)自己的引導(dǎo)程序,它不是Android操作系統(tǒng)的一部分。引導(dǎo)程序是OEM廠商或者運(yùn)營(yíng)商加鎖和限制的地方。
引導(dǎo)程序分兩個(gè)階段執(zhí)行。第一個(gè)階段,檢測(cè)外部的RAM以及加載對(duì)第二階段有用的程序;第二階段,引導(dǎo)程序設(shè)置網(wǎng)絡(luò)、內(nèi)存等等。這些對(duì)于運(yùn)行內(nèi)核是必要的,為了達(dá)到特殊的目標(biāo),引導(dǎo)程序可以根據(jù)配置參數(shù)或者輸入數(shù)據(jù)設(shè)置內(nèi)核。
Android引導(dǎo)程序可以在bootablebootloaderlegacyusbloader找到。
傳統(tǒng)的加載器包含的個(gè)文件,需要在這里說(shuō)明:
init.s初始化堆棧,清零BBS段,調(diào)用main.c的_main()函數(shù);
main.c初始化硬件(鬧鐘、主板、鍵盤、控制臺(tái)),創(chuàng)建linux標(biāo)簽。
更多關(guān)于Android引導(dǎo)程序的可以在這里了解。
第三步:內(nèi)核
Android內(nèi)核與桌面linux內(nèi)核啟動(dòng)的方式差不多。內(nèi)核啟動(dòng)時(shí),設(shè)置緩存、被保護(hù)存儲(chǔ)器、計(jì)劃列表,加載驅(qū)動(dòng)。當(dāng)內(nèi)核完成系統(tǒng)設(shè)置,它首先在系統(tǒng)文件中尋找”init”文件,然后啟動(dòng)root進(jìn)程或者系統(tǒng)的第一個(gè)進(jìn)程。
第四步:init進(jìn)程
init是第一個(gè)進(jìn)程,我們可以說(shuō)它是root進(jìn)程或者說(shuō)有進(jìn)程的父進(jìn)程。init進(jìn)程有兩個(gè)責(zé)任,一是掛載目錄,比如/sys、/dev、/proc,二是運(yùn)行init.rc腳本。
init進(jìn)程可以在/system/core/init找到。
init.rc文件可以在/system/core/rootdir/init.rc找到。
readme.txt可以在/system/core/init/readme.txt找到。
對(duì)于init.rc文件,Android中有特定的格式以及規(guī)則。在Android中,我們叫做Android初始化語(yǔ)言。
Action(動(dòng)作):動(dòng)作是以命令流程命名的,有一個(gè)觸發(fā)器決定動(dòng)作是否發(fā)生。
語(yǔ)法
1
2
3
4
5
; html-script: false ]
on trigger
command
command
command
Service(服務(wù)):服務(wù)是init進(jìn)程啟動(dòng)的程序、當(dāng)服務(wù)退出時(shí)init進(jìn)程會(huì)視情況重啟服務(wù)。
語(yǔ)法
1
2
3
4
5
; html-script: false ]
service name pathname [argument]*
option
option
...
Options(選項(xiàng))
選項(xiàng)是對(duì)服務(wù)的描述。它們影響init進(jìn)程如何以及何時(shí)啟動(dòng)服務(wù)。
咱們來(lái)看看默認(rèn)的init.rc文件。這里我只列出了主要的事件以及服務(wù)。
Table
Action/Service
描述
on early-init
設(shè)置init進(jìn)程以及它創(chuàng)建的子進(jìn)程的優(yōu)先級(jí),設(shè)置init進(jìn)程的安全環(huán)境
on init
設(shè)置全局環(huán)境,為cpu accounting創(chuàng)建cgroup(資源控制)掛載點(diǎn)
on fs
掛載mtd分區(qū)
on post-fs
改變系統(tǒng)目錄的訪問(wèn)權(quán)限
on post-fs-data
改變/data目錄以及它的子目錄的訪問(wèn)權(quán)限
on boot
基本網(wǎng)絡(luò)的初始化,內(nèi)存管理等等
service servicemanager
啟動(dòng)系統(tǒng)管理器管理所有的本地服務(wù),比如位置、音頻、Shared preference等等…
service zygote
啟動(dòng)zygote作為應(yīng)用進(jìn)程
在這個(gè)階段你可以在設(shè)備的屏幕上看到“Android”logo了。
第五步
在Java中,我們知道不同的虛擬機(jī)實(shí)例會(huì)為不同的應(yīng)用分配不同的內(nèi)存。假如Android應(yīng)用應(yīng)該盡可能快地啟動(dòng),但如果Android系統(tǒng)為每一個(gè)應(yīng)用啟動(dòng)不同的Dalvik虛擬機(jī)實(shí)例,就會(huì)消耗大量的內(nèi)存以及時(shí)間。因此,為了克服這個(gè)問(wèn)題,Android系統(tǒng)創(chuàng)造了”Zygote”。Zygote讓Dalvik虛擬機(jī)共享代碼、低內(nèi)存占用以及最小的啟動(dòng)時(shí)間成為可能。Zygote是一個(gè)虛擬器進(jìn)程,正如我們?cè)谇耙粋€(gè)步驟所說(shuō)的在系統(tǒng)引導(dǎo)的時(shí)候啟動(dòng)。Zygote預(yù)加載以及初始化核心庫(kù)類。通常,這些核心類一般是只讀的,也是Android SDK或者核心框架的一部分。在Java虛擬機(jī)中,每一個(gè)實(shí)例都有它自己的核心庫(kù)類文件和堆對(duì)象的拷貝。
Zygote加載進(jìn)程
加載ZygoteInit類,源代碼:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
registerZygoteSocket()為zygote命令連接注冊(cè)一個(gè)服務(wù)器套接字。
preloadClassed “preloaded-classes”是一個(gè)簡(jiǎn)單的包含一系列需要預(yù)加載類的文本文件,你可以在/frameworks/base找到“preloaded-classes”文件。
preloadResources() preloadResources也意味著本地主題、布局以及android.R文件中包含的所有東西都會(huì)用這個(gè)方法加載。
在這個(gè)階段,你可以看到啟動(dòng)動(dòng)畫。
第六步:系統(tǒng)服務(wù)或服務(wù)
完成了上面幾步之后,運(yùn)行環(huán)境請(qǐng)求Zygote運(yùn)行系統(tǒng)服務(wù)。系統(tǒng)服務(wù)同時(shí)使用native以及java編寫,系統(tǒng)服務(wù)可以認(rèn)為是一個(gè)進(jìn)程。同一個(gè)系統(tǒng)服務(wù)在Android SDK可以以System Services形式獲得。系統(tǒng)服務(wù)包含了所有的System Services。
Zygote創(chuàng)建新的進(jìn)程去啟動(dòng)系統(tǒng)服務(wù)。你可以在ZygoteInit類的”startSystemServer”方法中找到源代碼。
核心服務(wù):
啟動(dòng)電源管理器;
創(chuàng)建Activity管理器;
啟動(dòng)電話注冊(cè);
啟動(dòng)包管理器;
設(shè)置Activity管理服務(wù)為系統(tǒng)進(jìn)程;
啟動(dòng)上下文管理器;
啟動(dòng)系統(tǒng)Context Providers;
啟動(dòng)電池服務(wù);
啟動(dòng)定時(shí)管理器;
啟動(dòng)傳感服務(wù);
啟動(dòng)窗口管理器;
啟動(dòng)藍(lán)牙服務(wù);
啟動(dòng)掛載服務(wù)。
其他服務(wù):
啟動(dòng)狀態(tài)欄服務(wù);
啟動(dòng)硬件服務(wù);
啟動(dòng)網(wǎng)絡(luò)狀態(tài)服務(wù);
啟動(dòng)網(wǎng)絡(luò)連接服務(wù);
啟動(dòng)通知管理器;
啟動(dòng)設(shè)備存儲(chǔ)監(jiān)視服務(wù);
啟動(dòng)定位管理器;
啟動(dòng)搜索服務(wù);
啟動(dòng)剪切板服務(wù);
啟動(dòng)登記服務(wù);
啟動(dòng)壁紙服務(wù);
啟動(dòng)音頻服務(wù);
啟動(dòng)耳機(jī)監(jiān)聽(tīng);
啟動(dòng)AdbSettingsObserver(處理adb命令)。
第七步:引導(dǎo)完成
一旦系統(tǒng)服務(wù)在內(nèi)存中跑起來(lái)了,Android就完成了引導(dǎo)過(guò)程。在這個(gè)時(shí)候“ACTION_BOOT_COMPLETED”開(kāi)機(jī)啟動(dòng)廣播就會(huì)發(fā)出去。
Service(服務(wù))一個(gè)運(yùn)行在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行的操作組件,它不提供任何用戶界面,作為與Activity同級(jí)的組件,它依舊是運(yùn)行在主線程中。
其它組件可以啟動(dòng)一個(gè)Service,當(dāng)這個(gè)Service啟動(dòng)之后便會(huì)在后臺(tái)執(zhí)行,這里需要注意,由于是在主線程中,所以我們需要另外開(kāi)啟一個(gè)線程來(lái)執(zhí)行我們的耗時(shí)操作。
此外,一個(gè)組件還可以與一個(gè)Service進(jìn)行綁定來(lái)實(shí)現(xiàn)組件之間的交互,甚至可以執(zhí)行IPC(Inter-Process Communication)進(jìn)程間通信。
Service可以在后臺(tái)執(zhí)行很多任務(wù),比如處理網(wǎng)絡(luò)事務(wù),播放音樂(lè),文件讀寫或者與一個(gè)內(nèi)容提供者交互,等等。
本地服務(wù)(Local)
該服務(wù)依附在主進(jìn)程上而不是獨(dú)立的進(jìn)程,這樣在一定程度上節(jié)約了資源,另外本地服務(wù)因?yàn)槭窃谕贿M(jìn)程因此不需要IPC,也不需要AIDL。相應(yīng)bindService會(huì)方便很多,當(dāng)主進(jìn)程被Kill后,服務(wù)便會(huì)終止。一般使用在音樂(lè)播放器播放等不需要常駐的服務(wù)。
遠(yuǎn)程服務(wù)(Remote Service)
該服務(wù)是獨(dú)立的進(jìn)程,對(duì)應(yīng)進(jìn)程名格式為所在包名加上你指定的android:process字符串。一般定義方式 android:process=":service" 由于是獨(dú)立的進(jìn)程,因此在Activity所在進(jìn)程被Kill的時(shí)候,該服務(wù)依然在運(yùn)行,不受其他進(jìn)程影響,有利于為多個(gè)進(jìn)程提供服務(wù)具有較高的靈活性。由于是獨(dú)立的進(jìn)程,會(huì)占用一定資源,并且使用AIDL進(jìn)行IPC比較麻煩。一般用于系統(tǒng)的Service,這種Service是常駐的。
startService啟動(dòng)的服務(wù)
用于啟動(dòng)一個(gè)服務(wù)執(zhí)行后臺(tái)任務(wù),不與組件進(jìn)行通信,停止服務(wù)使用stopService。 當(dāng)一個(gè)應(yīng)用組件比如activity通過(guò)調(diào)用startService()來(lái)啟動(dòng)一個(gè)服務(wù)的時(shí)候,服務(wù)便處于啟動(dòng)狀態(tài)。一旦啟動(dòng),服務(wù)可以在后臺(tái)無(wú)限期地運(yùn)行下去,即使當(dāng)啟動(dòng)它的組件已經(jīng)銷毀。通常情況下,一個(gè)啟動(dòng)的service執(zhí)行一個(gè)單一的操作并且不會(huì)返回任何結(jié)果給調(diào)用者。
bindService啟動(dòng)的服務(wù)
用于啟動(dòng)的服務(wù)需要進(jìn)行通信。停止服務(wù)使用unbindService。 當(dāng)一個(gè)應(yīng)用組件通過(guò)調(diào)用bindService()來(lái)與一個(gè)服務(wù)綁定時(shí),服務(wù)便處于綁定狀態(tài)。一個(gè)綁定的服務(wù)提供了一個(gè)客戶端-服務(wù)器端接口來(lái)允許組件與服務(wù)進(jìn)行交互,發(fā)送請(qǐng)求,得到結(jié)果甚至通過(guò)IPC進(jìn)程間通信來(lái)完成操作。只有當(dāng)其它組件與服務(wù)進(jìn)行綁定時(shí),服務(wù)才會(huì)處于綁定狀態(tài)。多個(gè)組件可以同時(shí)與服務(wù)綁定,但是當(dāng)他們?nèi)慷冀獬壎〞r(shí),服務(wù)就會(huì)銷毀。
2.BindService:
如果一個(gè)Service在某個(gè)Activity中被調(diào)用bindService方法啟動(dòng),不論bindService被調(diào)用幾次,Service的 onCreate 方法只會(huì)執(zhí)行一次,同時(shí) onStartCommand 方法始終不會(huì)調(diào)用。當(dāng)建立連接后,Service會(huì)一直運(yùn)行,除非調(diào)用unbindService來(lái)接觸綁定、斷開(kāi)連接或調(diào)用該Service的Context不存在了(如Activity被Finish——即通過(guò)bindService啟動(dòng)的Service的生命周期依附于啟動(dòng)它的Context),系統(tǒng)在這時(shí)會(huì)自動(dòng)停止該Service。
3.StartService AND BindService:
當(dāng)一個(gè)Service在被啟動(dòng)(startService 的同時(shí)又被綁定(bindService ),該Service將會(huì)一直在后臺(tái)運(yùn)行,并且不管調(diào)用幾次, onCreate 方法始終只會(huì)調(diào)用一次, onStartCommand 的調(diào)用次數(shù)與startService 調(diào)用的次數(shù)一致(使用bindService 方法不會(huì)調(diào)用 onStartCommand )。同時(shí),調(diào)用unBindService 將不會(huì)停止Service,必須調(diào)用stopService 或Service自身的stopSelf 來(lái)停止服務(wù)。
4.停止Service:
當(dāng)一個(gè)服務(wù)被終止(stopService 、stopSelf 、unbindService )時(shí), onDestory 方法將會(huì)被調(diào)用——所以我們需要在該方法中清除一些工作(依附該Service生命周期上的,比如:停止在Service中創(chuàng)建并運(yùn)行的線程)。
1.創(chuàng)建服務(wù)
如果你才用的是 startService的方式那么 onBind方法可以忽略
2.注冊(cè)服務(wù)
3.開(kāi)啟服務(wù)
start:
bind
綁定服務(wù),一般涉及到組件或進(jìn)程之間的通信,既然需要通信,那么我們肯定需要一個(gè)連接,這里ServiceConnection就是我們所需要的連接,通過(guò)Ibinder的傳遞,我們可以獲取到Service的Ibinder對(duì)象,從而進(jìn)行相關(guān)操作。
關(guān)于粘性服務(wù),這里需要提到 Service的onStartCommand返回值
andorid:name
adroid:exported
android:enabled
android:label
android:process
android:icon
android:permission
關(guān)于服務(wù),當(dāng)我們?cè)趹?yīng)用開(kāi)發(fā)中,如果需要長(zhǎng)時(shí)間的在后臺(tái)運(yùn)行,獨(dú)立完成某一些事情的情況下,請(qǐng)使用Service!
此文綜合: 以及自己的一些問(wèn)題看法,用作學(xué)習(xí),回顧之用。
Service 前臺(tái)服務(wù)
請(qǐng)參看 紫豪
本文原文連接
Service是Android中的四大組件之一,它的級(jí)別和Activity差不多。只不過(guò)Service沒(méi)有頁(yè)面顯示,只能后臺(tái)運(yùn)行,可以和其他組件進(jìn)行交互。
Service的后臺(tái)運(yùn)行并不是子線程,是在主線程中進(jìn)行的,只是它沒(méi)有界面顯示。如果Service進(jìn)行了耗時(shí)操作同樣需要開(kāi)啟子線程,否則會(huì)跟Activity一樣出現(xiàn)ANR問(wèn)題(application not response–程序沒(méi)有響應(yīng))。
補(bǔ)充說(shuō)明:
主線程的內(nèi)容包括UI和后臺(tái),只要程序中的UI或者后臺(tái)其中一個(gè)在跑,程序都算是在運(yùn)行狀態(tài)。
1,創(chuàng)建一個(gè)自己的TestService繼承Service
2,必須實(shí)現(xiàn)重寫其中的onBind方法,可以在里邊做各種操作,也可以接收傳遞過(guò)來(lái)的Intent的數(shù)據(jù)。
(在Android Studio中可以直接新建一個(gè)Service)
服務(wù)的注冊(cè)是四大組件中最簡(jiǎn)單的一個(gè),一般只要設(shè)置name屬性就可以了。
1,startService()啟動(dòng)
(1)啟動(dòng)服務(wù)startService:onCerate(),onStart()
(2)停止服務(wù)stopService:onDestroy()
此方法啟動(dòng)服務(wù),服務(wù)如果未被創(chuàng)建,系統(tǒng)會(huì)先調(diào)用onCreate()方法,接著調(diào)用onStrat()方法。如果調(diào)用startService前服務(wù)已經(jīng)被啟動(dòng),多次調(diào)用啟動(dòng)方法,不會(huì)多次調(diào)用onCreate,但會(huì)導(dǎo)致多次調(diào)用onStrat。
2,bindService()啟動(dòng)
(1)綁定bindService:onCreate(),onBind()
(2)解除綁定unbindService:onUnbind()
(3)正常停止程序服務(wù)的方法是先接觸綁定unbindService,在停止服務(wù)stopService
綁定后調(diào)用stopService方法,這時(shí)候是不能停止服務(wù)的,如果這時(shí)再調(diào)用解綁unbindService,程序會(huì)先解綁,后停止服務(wù)。
用此方法啟動(dòng)服務(wù),在服務(wù)未被創(chuàng)建時(shí),會(huì)先調(diào)用onCreate(),接著調(diào)用onBind()方法,這時(shí)候調(diào)用者和服務(wù)綁定在一起,調(diào)用者退出,系統(tǒng)會(huì)先調(diào)用服務(wù)的onUnbind(),然后onDestroy()。如果調(diào)用bindService之前服務(wù)已經(jīng)被綁定,多次調(diào)用bindService并不會(huì)導(dǎo)致onCreate()和onBind()方法被多次調(diào)用。如果調(diào)用者想與正在綁定的服務(wù)解除綁定,可以調(diào)用unbindService()。
(1),onCerate()服務(wù)第一次被創(chuàng)建
(2),onStartComand()服務(wù)開(kāi)始工作
(3),onBind()服務(wù)已經(jīng)綁定
(4),onUnBind()服務(wù)解綁
(5),onDestroy()服務(wù)已經(jīng)停止
普通的Service進(jìn)行耗時(shí)操作要?jiǎng)?chuàng)建一個(gè)線程去完成,因?yàn)閟ervice是在主線程運(yùn)行的,并且這個(gè)子線程完成工作要手動(dòng)停止 。IntentService是繼承了Service并處理起步請(qǐng)求的一個(gè)類,在IntentService內(nèi)有一個(gè)工作線程,來(lái)處理耗時(shí)操作,啟動(dòng)IntentService的方式和啟動(dòng)傳統(tǒng)的Service是一樣,當(dāng)任務(wù)執(zhí)行完成后,IntentService會(huì)自動(dòng)停止,而不需要我們?nèi)タ刂啤?/p>
可以啟動(dòng)多次IntentService,每一個(gè)耗時(shí)操作會(huì)以工作隊(duì)列的方式在IntentService的onHandleIntent回調(diào)方法中執(zhí)行,并且每次只會(huì)執(zhí)行一個(gè)工作線程,執(zhí)行完第一個(gè)再執(zhí)行第二個(gè),以此類推,而且,所有請(qǐng)求都在一個(gè)單線程中,不會(huì)阻塞主線程,同一時(shí)間只處理一個(gè)請(qǐng)求。
IntentService優(yōu)點(diǎn)
1,省去了在Service中開(kāi)線程的麻煩
2,當(dāng)操作完成時(shí),不用手動(dòng)停止Service。IntentService是Service,但是比Service更智能。
網(wǎng)頁(yè)題目:android啟動(dòng)服務(wù),android啟動(dòng)器
文章來(lái)源:http://chinadenli.net/article4/dsdepoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、服務(wù)器托管、移動(dòng)網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣、動(dòng)態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)