Android操作系統(tǒng)知識(shí)詳解

? ? ? ?這篇博文主要是介紹Android操作系統(tǒng)中,個(gè)人匯總的比較重要的一些知識(shí)點(diǎn),在Android的系統(tǒng)四層結(jié)構(gòu)中(有些地方分為五層),作為應(yīng)用開發(fā)的程序員,我們常??赡苤魂P(guān)注最上層的應(yīng)用層,但是其實(shí)在我們操作或者使用某些系統(tǒng)接口時(shí),其實(shí)都無時(shí)無刻涉及到系統(tǒng)其它層級(jí)的知識(shí)點(diǎn),所以如果要做到“知其然,知其所以然”,深入理解系統(tǒng)其它層的知識(shí),對(duì)提高我們開發(fā)的視野也是很有幫助的,可能這就是別人常說的上帝視角吧,哈哈。


知識(shí)點(diǎn)匯總:

一:背景?

二:Android系統(tǒng)知識(shí)點(diǎn)匯總?

三:應(yīng)用程序?qū)又R(shí)點(diǎn)詳解?

四:應(yīng)用程序框架層知識(shí)點(diǎn)詳解?

五:系統(tǒng)運(yùn)行庫層知識(shí)點(diǎn)詳解?

六:Linux內(nèi)核層知識(shí)點(diǎn)詳解?

七:Android操作系統(tǒng)的演進(jìn)?

八:擴(kuò)展閱讀


一:背景

? ? ? ?Android 是Google開發(fā)的基于Linux平臺(tái)的開源手機(jī)操作系統(tǒng)。它包括操作系統(tǒng)、用戶界面和應(yīng)用程序 —— 移動(dòng)電話工作所需的全部軟件,而且不存在任何以往阻礙移動(dòng)產(chǎn)業(yè)創(chuàng)新的專有權(quán)障礙。Android采用WebKit瀏覽器引擎,具備觸摸屏、高級(jí)圖形顯示和上網(wǎng)功能,用戶能夠在手機(jī)上查看電子郵件、搜索網(wǎng)址和觀看視頻節(jié)目等,比iPhone等其他手機(jī)更強(qiáng)調(diào)搜索功能,界面更強(qiáng)大,可以說是一種融入全部Web應(yīng)用的單一平臺(tái)。


Android系統(tǒng)架構(gòu)圖:???????

? ? ? ?Android的系統(tǒng)架構(gòu)和其操作系統(tǒng)一樣,采用了分層的架構(gòu)。從架構(gòu)圖看,android分為四個(gè)層,從高層到低層分別是應(yīng)用程序?qū)?、?yīng)用程序框架層、系統(tǒng)運(yùn)行庫層和linux核心層。

Android系統(tǒng)架構(gòu)圖:(五層結(jié)構(gòu))

第一層:應(yīng)用程序?qū)?/p>

? ?Android會(huì)同一系列核心應(yīng)用程序包一起發(fā)布,該應(yīng)用程序包包括email客戶端,SMS短消息程序,日歷,地圖,瀏覽器,聯(lián)系人管理程序等,所有的應(yīng)用程序都是使用JAVA語言編寫的。

第二層:應(yīng)用程序框架層

? ? ? ?開發(fā)人員也可以完全訪問核心應(yīng)用程序所使用的API框架,該應(yīng)用程序的架構(gòu)設(shè)計(jì)簡化了組件的重用,任何一個(gè)應(yīng)用程序都可以發(fā)布它的功能塊并且任何其它的應(yīng)用程序都可以使用其所發(fā)布的功能塊(不過得遵循框架的安全性限制)。 ????????

? ? ? ?同樣,該應(yīng)用程序重用機(jī)制也使用戶可以方便的替換程序組件,這一層的是由Java代碼編寫的,可以稱為Java Framework。

? ? ? ? 隱藏在每個(gè)應(yīng)用后面的是一系列的服務(wù)和系統(tǒng), 其中包括:

第三層:系統(tǒng)運(yùn)行庫層

模塊一:C/C++程序庫

? ? ? ?Android 包含一些C/C++庫,這些庫能被Android系統(tǒng)中不同的組件使用。它們通過 Android 應(yīng)用程序框架為開發(fā)者提供服務(wù)。

模塊二:Android 運(yùn)行時(shí)庫 ???

? ? ? ?Android 包括了一個(gè)核心庫,該核心庫提供了JAVA編程語言核心庫的大多數(shù)功能。 ???????

? ? ? ?每一個(gè)Android應(yīng)用程序都在它自己的進(jìn)程中運(yùn)行,都擁有一個(gè)獨(dú)立的Dalvik虛擬機(jī)實(shí)例。Dalvik被設(shè)計(jì)成一個(gè)設(shè)備可以同時(shí)高效地運(yùn)行多個(gè)虛擬系統(tǒng)。 Dalvik虛擬機(jī)執(zhí)行(.dex)的Dalvik可執(zhí)行文件,該格式文件針對(duì)小內(nèi)存使用做了優(yōu)化。同時(shí)虛擬機(jī)是基于寄存器的,所有的類都經(jīng)由JAVA編譯器編譯,然后通過SDK中 的 "dx" 工具轉(zhuǎn)化成.dex格式由虛擬機(jī)執(zhí)行。

? ? ? ? Dalvik虛擬機(jī)依賴于linux內(nèi)核的一些功能,比如線程機(jī)制和底層內(nèi)存管理機(jī)制。

第四層:硬件抽象層(HAL)???????

? ? ? ?硬件抽象層是位于操作系統(tǒng)內(nèi)核與硬件電路之間的接口層,其目的在于將硬件抽象化,為了保護(hù)硬件廠商的知識(shí)產(chǎn)權(quán),它隱藏了特定平臺(tái)的硬件接口細(xì)節(jié),為操作系統(tǒng)提供虛擬硬件平臺(tái),使其具有硬件無關(guān)性,可在多種平臺(tái)上進(jìn)行移植。 從軟硬件測試的角度來看,軟硬件的測試工作都可分別基于硬件抽象層來完成,使得軟硬件測試工作的并行進(jìn)行成為可能。通俗來講,就是將控制硬件的動(dòng)作放在硬件抽象層中。

第五層:Linux 內(nèi)核層???????

? ? ? ?Android 的核心系統(tǒng)服務(wù)依賴于 Linux 2.6 內(nèi)核,如安全性,內(nèi)存管理,進(jìn)程管理, 網(wǎng)絡(luò)協(xié)議棧和驅(qū)動(dòng)模型。Linux 內(nèi)核也同時(shí)作為硬件和軟件棧之間的抽象層。 (Android 5.0內(nèi)核層改為Linux 3.0)


二:Android系統(tǒng)知識(shí)點(diǎn)匯總?

知識(shí)點(diǎn)一:應(yīng)用的安裝過程詳解

安裝流程:

1、啟動(dòng)由packageinstaller.apk應(yīng)用處理安裝及卸載過程的界面,點(diǎn)擊安裝。?

2、通過Binder與PackageManagerService通信,需要系統(tǒng)服務(wù)提供apk的安裝服務(wù)。?

3、復(fù)制APK安裝包到data/app目錄下,解壓并掃描安裝包,把dex文件(Dalvik字節(jié)碼)保存到dalvik-cache目錄,并data/data目錄下創(chuàng)建對(duì)應(yīng)的應(yīng)用數(shù)據(jù)目錄。?

4、完成安裝,發(fā)送Intent.ACTION_PACKAGE_ADDED廣播。

應(yīng)用安裝涉及到如下幾個(gè)目錄:????????

1、data/app??---------------用戶程序安裝的目錄,安裝時(shí)把a(bǔ)pk文件復(fù)制到此錄。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2、data/data ---------------存放應(yīng)用程序的數(shù)據(jù)。

3、data/dalvik-cache--------將apk中的dex文件安裝到dalvik-cache目錄下(dex文件是dalvik虛擬機(jī)的可執(zhí)行文件,其大小約為原始apk文件大小的四分之一)。


知識(shí)點(diǎn)二:應(yīng)用的啟動(dòng)過程

過程概況:

1、Launcher所在進(jìn)程通過binder發(fā)送消息給system_server進(jìn)程;?

2、system_server進(jìn)程調(diào)用Process.start()方法向Zygote進(jìn)程發(fā)出創(chuàng)建新進(jìn)程請(qǐng)求。關(guān)于system server在上面的系統(tǒng)啟動(dòng)流程中有提到,它是zygote的第一個(gè)子進(jìn)程。?

3、zygote進(jìn)程fork自身,開啟一個(gè)Linux進(jìn)程和一個(gè)主線程。ZygoteInit.main()方法來實(shí)例化Activity Thread對(duì)象,并最終返回新進(jìn)程的pid給ActivityManagerService。

4、ActivityThread隨后依次調(diào)用Looper.prepareLoop()和Looper.loop()來開啟消息循環(huán)。?

5、通過ActivityThread把新建的進(jìn)程和Application綁定,然后加載app的classes到內(nèi)存中。?

6、啟動(dòng) Activity。

啟動(dòng)過程圖解:

知識(shí)點(diǎn)三:系統(tǒng)的啟動(dòng)過程與核心進(jìn)程的作用

Android系統(tǒng)啟動(dòng)流程,如下所示。

1、啟動(dòng)電源以及系統(tǒng)啟動(dòng) 當(dāng)電源按下時(shí)引導(dǎo)芯片代碼開始從預(yù)定義的地方(固化在ROM)開始執(zhí)行。加載引導(dǎo)程序Bootloader到RAM,然后執(zhí)行。?

2、引導(dǎo)程序BootLoader 引導(dǎo)程序BootLoader是在Android操作系統(tǒng)開始運(yùn)行前的一個(gè)小程序,它的主要作用是把系統(tǒng)OS拉起來并運(yùn)行。?

3、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.rc文件,并啟動(dòng)init進(jìn)程。?

4、init進(jìn)程啟動(dòng) 初始化和啟動(dòng)屬性服務(wù),并且啟動(dòng)Zygote進(jìn)程。?

5、Zygote進(jìn)程啟動(dòng) 創(chuàng)建JavaVM并為JavaVM注冊(cè)JNI,創(chuàng)建服務(wù)端Socket,啟動(dòng)SystemServer進(jìn)程。?

6、SystemServer進(jìn)程啟動(dòng) 啟動(dòng)Binder線程池和SystemServiceManager,并且啟動(dòng)各種系統(tǒng)服務(wù)。 7.Launcher啟動(dòng) 被SystemServer進(jìn)程啟動(dòng)的ActivityManagerService會(huì)啟動(dòng)Launcher,Launcher啟動(dòng)后會(huì)將已安裝應(yīng)用的快捷圖標(biāo)顯示到界面上。

核心進(jìn)程:

1、Init進(jìn)程描述:

? ? ? ?當(dāng)初始化內(nèi)核之后,就會(huì)啟動(dòng)一個(gè)相當(dāng)重要的祖先進(jìn)程,也就是init進(jìn)程,在Linux中所有的進(jìn)程都是由init進(jìn)程直接或間接fork出來的。init進(jìn)程負(fù)責(zé)創(chuàng)建系統(tǒng)中最關(guān)鍵的幾個(gè)核心daemon(守護(hù))進(jìn)程,尤其是zygote和servicemanager。前者是android啟動(dòng)的第一個(gè)dalvik 虛擬機(jī),它將負(fù)責(zé)啟動(dòng)Java世界的進(jìn)程;后者是BInder通信的基礎(chǔ)。另外,它還提供了property service(屬性服務(wù)),類似于windows系統(tǒng)的注冊(cè)表服務(wù)。

2、Zygote進(jìn)程(系統(tǒng)兩大核心進(jìn)程之一)描述:

? ? ? ?這是一個(gè)Android平臺(tái)的非?;A(chǔ)的進(jìn)程. 這個(gè)進(jìn)程初始化了第一個(gè)VM, 并且預(yù)加載了framework和眾多App所需要的通用資源. 然后它開啟一個(gè)Socket接口來監(jiān)聽請(qǐng)求, 根據(jù)請(qǐng)求孵化出新的VM來管理新的App進(jìn)程. 一旦收到新的請(qǐng)求, Zygote會(huì)基于自身預(yù)先加載的VM來孵化出一個(gè)新的VM創(chuàng)建一個(gè)新的進(jìn)程,Zygote 的中文意思是受精卵,從這個(gè)意思里也可以看出 Zygote 進(jìn)程是用來分裂復(fù)制(fork)的,實(shí)際上所有的 App 進(jìn)程都是通過對(duì) Zygote 進(jìn)程的 Fork 得來的。

3、SystemService進(jìn)程(系統(tǒng)兩大核心進(jìn)程之一)描述:

? ? ? ?這個(gè)進(jìn)程在整個(gè)的Android中非常重要,它和Zygote進(jìn)程一樣,是Android Framework層的兩大重要進(jìn)程。系統(tǒng)里面重要的服務(wù)都是在這個(gè)進(jìn)程里面開啟的,例如ActivityManagerService, WindowsManagerService, PackageManagerService等等都是由這個(gè)SystemServer fork出來的。 ?

4、SystemServiceManager進(jìn)程描述:

? ? ? ?SystemServiceManager管理各個(gè)service,用SystemServiceManager啟動(dòng)service的時(shí)候,會(huì)把service加入自己的鏈表。并且調(diào)用service的onStart函數(shù),在SystemServer中啟動(dòng)的各種服務(wù),在ServiceManager中注冊(cè)的是用于進(jìn)程間通信的。?

5、MediaManager進(jìn)程描述:

? ? ? ?是整個(gè)Android中media部分的核心和靈魂。幾乎所有與多媒體播放相關(guān)的內(nèi)容都放在這里。包括了音視頻的編解碼以及顯示輸出,分別是創(chuàng)建各個(gè)子模塊的對(duì)象實(shí)例,例如:AudioFlinger,MediaPlayerService,CameraService,AudioPolicyService等。

6、Android系統(tǒng)守護(hù)進(jìn)程守護(hù)進(jìn)程: 一直在后臺(tái)運(yùn)行的進(jìn)程。 在init.rc中定義了很多系統(tǒng)的守護(hù)進(jìn)程:?

1、uevent:負(fù)責(zé)相應(yīng)uevent事件,創(chuàng)建設(shè)備節(jié)點(diǎn)文件。?

2、console:包含常用的shell命令、如ls、cd等。?

3、adbd:abd的守護(hù)進(jìn)程。?

4、servicemanager:binder的服務(wù)總管,負(fù)責(zé)binder服務(wù)的注冊(cè)和查找。?

5、vold:負(fù)責(zé)完成系統(tǒng)USB存儲(chǔ)卡等擴(kuò)展存儲(chǔ)自動(dòng)掛載的守護(hù)進(jìn)程。?

6、netd:Android 網(wǎng)絡(luò)守護(hù)進(jìn)程。?

7、debuggerd:負(fù)責(zé)異常退出的診斷。如果偵測到程序崩潰,debuggerd將把崩潰時(shí)的進(jìn)程狀態(tài)信息輸出到文件和串口中,供開發(fā)人員分析和調(diào)試使用。?

8、ril-deamon:手機(jī)底層的通信系統(tǒng)的守護(hù)進(jìn)程。?

9、surfaceflinger:負(fù)責(zé)合成系統(tǒng)所有顯示圖層的服務(wù)進(jìn)程。?

10、media:系統(tǒng)多媒體部分的守護(hù)進(jìn)程,包含了audio、mediaplayer以及camera 等系統(tǒng)服務(wù)。

11、bootanim:播放開機(jī)動(dòng)畫的進(jìn)程。?

12、installd:Android的安裝服務(wù)守護(hù)進(jìn)程。?

13、lmkd:lowmemorykiller的守護(hù)進(jìn)程,Java層的LowMemoryKiller最終都是由lmkd來完成。


知識(shí)點(diǎn)四:進(jìn)程之間的通信方式(暫不包含Binder)

管道:管道可用于具有親緣關(guān)系進(jìn)程間的通信,允許一個(gè)進(jìn)程和另一個(gè)與它有共同祖先的進(jìn)程之間進(jìn)行通信,在創(chuàng)建時(shí)分配一個(gè)page大小的內(nèi)存,緩存區(qū)大小比較有限。

命名管道(named pipe):命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關(guān)系進(jìn)程間的通信。命名管道在文件系統(tǒng)中有對(duì)應(yīng)的文件名。命名管道通過命令mkfifo或系統(tǒng)調(diào)用mkfifo來創(chuàng)建。

消息(Message)隊(duì)列:消息隊(duì)列是消息的鏈接表,包括Posix消息隊(duì)列system V消息隊(duì)列。有足夠權(quán)限的進(jìn)程可以向隊(duì)列中添加消息,被賦予讀權(quán)限的進(jìn)程則可以讀走隊(duì)列中的消息。消息隊(duì)列克服了信號(hào)承載信息量少,管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn),信息復(fù)制兩次,額外的CPU消耗;不合適頻繁或信息量大的通信。

共享內(nèi)存:使得多個(gè)進(jìn)程可以訪問同一塊內(nèi)存空間,是最快的可用IPC形式。是針對(duì)其他通信機(jī)制運(yùn)行效率較低而設(shè)計(jì)的。往往與其它通信機(jī)制,如信號(hào)量結(jié)合使用,來達(dá)到進(jìn)程間的同步及互斥,無須復(fù)制,共享緩沖區(qū)直接附加到進(jìn)程虛擬地址空間,速度快;但進(jìn)程間的同步問題操作系統(tǒng)無法實(shí)現(xiàn),必須各進(jìn)程利用同步工具解決。

套接口(Socket):更為一般的進(jìn)程間通信機(jī)制,可用于不同機(jī)器之間的進(jìn)程間通信。起初是由Unix系統(tǒng)的BSD分支開發(fā)出來的,但現(xiàn)在一般可以移植到其它類Unix系統(tǒng)上:Linux和System V的變種都支持套接字,作為更通用的接口,傳輸效率低,主要用于不同機(jī)器或跨網(wǎng)絡(luò)的通信。

內(nèi)存映射(mapped memory):內(nèi)存映射允許任何多個(gè)進(jìn)程間通信,每一個(gè)使用該機(jī)制的進(jìn)程通過把一個(gè)共享的文件映射到自己的進(jìn)程地址空間來實(shí)現(xiàn)它。

信號(hào)量(semaphore):主要作為進(jìn)程間以及同一進(jìn)程不同線程之間的同步手段,常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問共享資源時(shí),其他進(jìn)程也訪問該資源。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。

信號(hào)(Signal):信號(hào)是比較復(fù)雜的通信方式,用于通知接受進(jìn)程有某種事件發(fā)生,除了用于進(jìn)程間通信外,進(jìn)程還可以發(fā)送信號(hào)給進(jìn)程本身;linux除了支持Unix早期信號(hào)語義函數(shù)sigal外,還支持語義符合Posix.1標(biāo)準(zhǔn)的信號(hào)函數(shù)sigaction(實(shí)際上,該函數(shù)是基于BSD的,BSD為了實(shí)現(xiàn)可靠信號(hào)機(jī)制,又能夠統(tǒng)一對(duì)外接口,用sigaction函數(shù)重新實(shí)現(xiàn)了signal函數(shù)),不適用于信息交換,更適用于進(jìn)程中斷控制,比如非法內(nèi)存訪問,殺死某個(gè)進(jìn)程等。

用于進(jìn)程間通訊(IPC)的四種不同技術(shù):???共享內(nèi)存,臨界區(qū),管道,消息

1. 消息傳遞(管道,FIFO,posix和system???v消息隊(duì)列)????

2. 同步(互斥鎖,條件變量,讀寫鎖,文件和記錄鎖,Posix和System???V信號(hào)燈)????

3. 共享內(nèi)存區(qū)(匿名共享內(nèi)存區(qū),有名Posix共享內(nèi)存區(qū),有名System???V共享內(nèi)存區(qū))????

4. 過程調(diào)用(Solaris門,Sun???RPC)??


知識(shí)點(diǎn)五:系統(tǒng)服務(wù)有哪些,分別實(shí)現(xiàn)的主要功能

描述:java系統(tǒng)服務(wù)由SystemServer系統(tǒng)進(jìn)程啟動(dòng),它分為:核心平臺(tái)服務(wù)和硬件服務(wù)。

一:核心平臺(tái)服務(wù)

? ? ? ?一般不會(huì)與應(yīng)用程序進(jìn)行交互,他們是Android Framework運(yùn)行所必須的服務(wù)。

AMS(Activity Manager Service):

? ? ? ?是Android中最核心的服務(wù),主要負(fù)責(zé)系統(tǒng)中四大組件的啟動(dòng)、切換、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度,管理所有activity的生命周期與堆棧等工作,其職責(zé)與操作系統(tǒng)中的進(jìn)程管理和調(diào)度模塊相類似,因此它在Android中非常重要。

WMS(Window Manager Service):

? ? ? ? Android系統(tǒng)中的窗口也是以堆棧的形式組織在WindowManagerService服務(wù)中的,其中,Z軸位置較低的窗口位于Z軸位置較高的窗口的下面,其位于surface Flinger之上,將要繪制到機(jī)器畫面上的內(nèi)容傳遞給Surface Flinger。

PMS(Package Manager Service):

? ? ? ?用來管理所有的package信息,包括安裝、卸載、更新以及解析AndroidManifest.xml以組織相應(yīng)的數(shù)據(jù)結(jié)構(gòu),加載apk文件(android包文件)的信息,提供信息顯示系統(tǒng)中設(shè)置了哪些包,以及加載了哪些包,這些數(shù)據(jù)結(jié)構(gòu)將會(huì)被PMS、ActivityMangerService等等service和application使用到。

硬件服務(wù):提供了一系列的API,用于控制底層的硬件。

AlarmManagerService:在特定時(shí)間后運(yùn)行指定的應(yīng)用程序,就像定時(shí)器。

ConnectivityService:提供有關(guān)網(wǎng)絡(luò)當(dāng)前狀態(tài)的信息。?

LocationService:提供終端當(dāng)前的位置信息。?

PowerService:設(shè)備電源管理。?

SensorService:提供Android中各種傳感器(磁力感應(yīng)器,加速度傳感器等)的感應(yīng)值。 TelephonyService:提供話機(jī)狀態(tài)及電話服務(wù)。 WifiService:控制無線網(wǎng)絡(luò)連接,如AP搜索,連接列表管理等。


知識(shí)點(diǎn)六:如何調(diào)用C/C++編寫的程序庫

JNI介紹:

定義:Java Native Interface,即 Java本地接口。?

作用: 使得Java與本地其他類型語言(如C、C++)交互,即在 Java代碼 里調(diào)用 C、C++等語言的代碼 或??C、C++代碼調(diào)用 Java 代碼,因?yàn)?Java 具備跨平臺(tái)的特點(diǎn),所以Java 與 本地代碼交互的能力非常弱,采用 JNI特性增強(qiáng) Java 與本地代碼交互的能力。?

?特別注意: JNI是 Java 調(diào)用 Native 語言的一種特性。 JNI 是屬于 Java 的,與 Android 無直接關(guān)系。

代碼實(shí)現(xiàn)步驟:

1、在Java中聲明Native方法(即需要調(diào)用的本地方法)。?

2、編譯上述 Java源文件javac(得到 .class文件)。?

3、通過javah 命令導(dǎo)出JNI的頭文件(.h文件)。?

4、使用Java調(diào)用需要交互的本地代碼實(shí)現(xiàn)在 Java中聲明的Native方法,如Java 需要與C++ 交互,那么就用C++實(shí)現(xiàn)Java的Native方法。?

5、編譯.so庫文件。?

6、通過Java命令執(zhí)行Java程序,最終實(shí)現(xiàn)Java調(diào)用本地代碼。

NDK介紹:

定義:Native Development Kit,是Android的一個(gè)工具開發(fā)包,NDK是屬于 Android 的,與Java并無直接關(guān)系。

作用:快速開發(fā)C、 C++的動(dòng)態(tài)庫,并自動(dòng)將so和應(yīng)用一起打包成 APK即可通過 NDK在Android中使用JNI與本地代碼(如C、C++)交互。

使用場景:在Android的場景下使用JNI,即 Android開發(fā)的功能需要本地代碼(C/C++)實(shí)現(xiàn)。

NDK特點(diǎn):

NDK與JNI關(guān)系:

知識(shí)點(diǎn)七:JVM,DVM,ART虛擬機(jī)的演進(jìn)

什么是虛擬機(jī):虛擬機(jī)是指通過軟件模擬的具有完整硬件系統(tǒng)功能的、運(yùn)行在一個(gè)完全隔離環(huán)境中的完整計(jì)算機(jī)系統(tǒng)。

Android中虛擬機(jī)的使用:我們都知道android程序的運(yùn)行是基于java語言的,也就是說運(yùn)行android程序需要類似在JVM的虛擬機(jī)之上運(yùn)行的,那讓我們來了解一下JVM。

什么是JVM:JVM本質(zhì)上就是一個(gè)軟件,是計(jì)算機(jī)硬件的一層軟件抽象,在這之上才能夠運(yùn)行Java程序,JAVA在編譯后會(huì)生成類似于匯編語言的JVM字節(jié)碼,與C語言編譯后產(chǎn)生的匯編語言不同的是,C編譯成的匯編語言會(huì)直接在硬件上跑,但JAVA編譯后生成的字節(jié)碼是在JVM上跑,需要由JVM把字節(jié)碼翻譯成機(jī)器指令,才能使JAVA程序跑起來。

為什么google要在JVM基礎(chǔ)上重新開發(fā)DVM?

? ?JVM虛擬機(jī)可以運(yùn)行在服務(wù)器上,PC上,也可以運(yùn)行在移動(dòng)設(shè)備上,并根據(jù)不同的運(yùn)行硬件會(huì)設(shè)計(jì)出不用的JVM虛擬機(jī),為了能針對(duì)移動(dòng)設(shè)備設(shè)計(jì)特有的硬件環(huán)境,使應(yīng)用程序盡可能流暢的運(yùn)行,在設(shè)計(jì)虛擬機(jī)需要重點(diǎn)關(guān)注哪些要點(diǎn)呢?1、如何用更少的內(nèi)存來運(yùn)行程序。(節(jié)約內(nèi)存) 2、如何用更少的CPU處理資源來運(yùn)行程序。(節(jié)約CPU資源) 3、在程序生成,運(yùn)行的過程中,如何用更少的存儲(chǔ)空間使程序也能正常運(yùn)行。

google在DVM的優(yōu)化:

優(yōu)化點(diǎn)一:CLASS變?yōu)镈EX???????

? ? ? JAVA虛擬機(jī)運(yùn)行的是JAVA字節(jié)碼,Dalvik虛擬機(jī)運(yùn)行的是Dalvik字節(jié)碼,JAVA程序經(jīng)過編譯,生成JAVA字節(jié)碼保存在class文件中,JVM通過解碼class文件中的內(nèi)容來運(yùn)行程序。而DVM運(yùn)行的是Dalvik字節(jié)碼,所有的Dalvik字節(jié)碼由JAVA字節(jié)碼轉(zhuǎn)換而來,并被打包到一個(gè)DEX(Dalvik Executable)可執(zhí)行文件中,DVM通過解釋DEX文件來執(zhí)行這些字節(jié)碼 , Dalvik可執(zhí)行文件體積更?。簽榱藴p小執(zhí)行文件的體積,安卓使用Dalvik虛擬機(jī),SDK中有個(gè)dx工具負(fù)責(zé)將JAVA字節(jié)碼轉(zhuǎn)換為Dalvik字節(jié)碼,dx工具對(duì)JAVA類文件重新排列,將所有JAVA類文件中的常量池分解,消除其中的冗余信息,重新組合形成一個(gè)常量池,所有的類文件共享同一個(gè)常量池,使得相同的字符串、常量在DEX文件中只出現(xiàn)一次,Dex這么設(shè)計(jì)可以使文件更緊湊,減少攏余,還可以共享資源,進(jìn)而減少文件大小。

JVM虛擬機(jī)與DVM虛擬機(jī)的執(zhí)行文件的區(qū)別:

優(yōu)化點(diǎn)二:基于棧變?yōu)榛诩拇嫫?/p>

???????JAVA虛擬機(jī)基于棧結(jié)構(gòu),程序在運(yùn)行時(shí)虛擬機(jī)需要頻繁的從棧上讀取寫入數(shù)據(jù),這個(gè)過程需要更多的指令分派與內(nèi)存訪問次數(shù),會(huì)耗費(fèi)很多CPU時(shí)間,Dalvik虛擬機(jī)基于寄存器架構(gòu),數(shù)據(jù)的訪問通過寄存器間直接傳遞,這樣的訪問方式比基于棧方式要快很多。

優(yōu)化點(diǎn)三: 每一個(gè)DVM實(shí)例都是一個(gè)獨(dú)立的進(jìn)程空間

???????每一個(gè)Android應(yīng)用都允許在自己的DVM實(shí)例中。每一個(gè)DVM實(shí)例都是一個(gè)獨(dú)立的進(jìn)程空間,所有Android的線程都對(duì)應(yīng)Linux的線程,DVM可以更多地依賴操作系統(tǒng)的線程調(diào)度和管理機(jī)制,不同應(yīng)用都是用不同的Linux用戶運(yùn)行以最大程度保護(hù)用戶應(yīng)用程序的安全性和獨(dú)立性。

google為什么后期又推出ART虛擬機(jī)替代DVM虛擬機(jī)?

? ? ? ?通過上面的描述,我們大概了解了谷歌在開始設(shè)計(jì)虛擬機(jī)的時(shí)候,在JVM的基礎(chǔ)上做了各種優(yōu)化,從而有了DVM虛擬機(jī),那在android 4.4之后,為什么谷歌使用了新的ART虛擬機(jī),ART虛擬機(jī)又有了什么新的優(yōu)點(diǎn)來適應(yīng)移動(dòng)設(shè)備環(huán)境。????????Android操作系統(tǒng)已經(jīng)成熟,Google的Android團(tuán)隊(duì)開始將注意力轉(zhuǎn)向一些底層組件,其中之一是負(fù)責(zé)應(yīng)用程序運(yùn)行的Dalvik運(yùn)行時(shí),Google開發(fā)者已經(jīng)花了兩年時(shí)間開發(fā)更快執(zhí)行效率更高更省電的ART,替代Dalvik運(yùn)行時(shí)。 ????????

? ? ? ?ART代表Android Runtime,其處理應(yīng)用程序執(zhí)行的方式完全不同于Dalvik,Dalvik是依靠一個(gè)Just-In-Time(JIT)編譯器去解釋字節(jié)碼。開發(fā)者編譯后的應(yīng)用代碼需要通過一個(gè)解釋器在用戶的設(shè)備上運(yùn)行,這一機(jī)制并不高效,但讓應(yīng)用能更容易在不同硬件和架構(gòu)上運(yùn)行。ART則完全改變了這套做法,在應(yīng)用安裝的時(shí)候就預(yù)編譯字節(jié)碼到機(jī)器語言,這一機(jī)制叫Ahead-Of-Time(AOT)編譯。在移除解釋代碼這一過程后,應(yīng)用程序執(zhí)行將更有效率,啟動(dòng)更快。

那么從DVM變?yōu)锳RT會(huì)有那方面的優(yōu)缺點(diǎn)呢?

優(yōu)點(diǎn):

1、系統(tǒng)性能的顯著提升。?

2、應(yīng)用啟動(dòng)更快、運(yùn)行更快、體驗(yàn)更流暢、觸感反饋更及時(shí)。?

3、更長的電池續(xù)航能力。?

4、支持更低的硬件。?

?缺點(diǎn):

1、更大的存儲(chǔ)空間占用,可能會(huì)增加10%-20%。

2、更長的應(yīng)用安裝時(shí)間。


知識(shí)點(diǎn)八:Android系統(tǒng)的進(jìn)程層級(jí)

描述:Android中,同一個(gè)應(yīng)用的所有組件在默認(rèn)情況下都運(yùn)行在同一個(gè)進(jìn)程中,但也可以通過修改manifest文件中的android:process屬性來指定該組件要運(yùn)行中那個(gè)進(jìn)程,也可以讓不同應(yīng)用的組件們運(yùn)行在同一個(gè)進(jìn)程中,當(dāng)然這些應(yīng)用要共享一個(gè)用戶ID,并且有相同的數(shù)字證書。????????

? ? ? ?Android可能在某個(gè)時(shí)刻決定關(guān)閉一個(gè)進(jìn)程,當(dāng)決定要關(guān)閉那些進(jìn)程的時(shí)候,系統(tǒng)會(huì)衡量每個(gè)進(jìn)程與用戶的緊密程度,這時(shí)候就跟Android中進(jìn)程的級(jí)別有關(guān)了。像一個(gè)具有可見的activity的進(jìn)程要比那些activity都是不可見的進(jìn)程擁有更高的等級(jí),更不容易被系統(tǒng)殺死。

? ? ??Android的進(jìn)程等級(jí)有那些呢?

前臺(tái)進(jìn)程:(foreground process)???????

? ? ? 用戶當(dāng)前正在做的事情需要這個(gè)進(jìn)程。如果滿足下面的條件之一,一個(gè)進(jìn)程就被認(rèn)為是前臺(tái)進(jìn)程:?

1、這個(gè)進(jìn)程擁有一個(gè)正在與用戶交互的Activity(這個(gè)Activity的onResume()方法被調(diào)用)。?

2、這個(gè)進(jìn)程擁有一個(gè)綁定到正在與用戶交互的activity上的Service。?

3、這個(gè)進(jìn)程擁有一個(gè)前臺(tái)運(yùn)行的Service(service調(diào)用了方法startForeground()).?

4、這個(gè)進(jìn)程擁有一個(gè)正在執(zhí)行其任何一個(gè)生命周期回調(diào)方法(onCreate(),onStart(),或onDestroy())的Service。?

5、這個(gè)進(jìn)程擁有正在執(zhí)行其onReceive()方法的BroadcastReceiver。 ???????

? ? ? 通常,在任何時(shí)間點(diǎn),只有很少的前臺(tái)進(jìn)程存在。它們只有在達(dá)到無法調(diào)合的矛盾時(shí)才會(huì)被殺--如內(nèi)存太小而不能繼續(xù)運(yùn)行時(shí)。通常,到了這時(shí),設(shè)備就達(dá)到了一個(gè)內(nèi)存分頁調(diào)度狀態(tài),所以需要?dú)⒁恍┣芭_(tái)進(jìn)程來保證用戶界面的反應(yīng)。

可見進(jìn)程:(visible process)???????

? ? ? ?沒有任何前臺(tái)組件,但是仍然能影響用戶在屏幕上看到東西。一個(gè)進(jìn)程滿足下面任何一個(gè)條件都被認(rèn)為是可視的:?

1、寄宿著一個(gè)不是前臺(tái)的活動(dòng),但是它對(duì)用戶仍可見(它的onPause()方法已經(jīng)被調(diào)用)。舉例來說,這可能發(fā)生在,如果一個(gè)前臺(tái)活動(dòng)在一個(gè)對(duì)話框(其他進(jìn)程的)運(yùn)行之后仍然是可視的,比如輸入法的彈出時(shí)。?

2、寄宿著一個(gè)服務(wù),該服務(wù)綁定到一個(gè)可視的活動(dòng)。

服務(wù)進(jìn)程(Service process):???????

? ? ? 是一個(gè)運(yùn)行著一個(gè)用startService()方法啟動(dòng)的服務(wù),并且該服務(wù)并沒有落入上面2種分類。雖然服務(wù)進(jìn)程沒有直接關(guān)系到任何用戶可見的,它們通常做用戶關(guān)心的事(諸如在后臺(tái)播放mp3或者從網(wǎng)絡(luò)上下載數(shù)據(jù)),因此系統(tǒng)保持它們運(yùn)行,除非沒有足夠內(nèi)存來保證所有的前臺(tái)進(jìn)程和可視進(jìn)程。

后臺(tái)進(jìn)程(Background process):???????

? ? ? ?是一個(gè)保持著一個(gè)當(dāng)前對(duì)用戶不可視的活動(dòng)(已經(jīng)調(diào)用Activity對(duì)象的onStop()方法)(如果還有除了UI線程外其他線程在運(yùn)行話,不受影響)。這些進(jìn)程沒有直接影響用戶體驗(yàn),并且可以在任何時(shí)候被殺以收回內(nèi)存用于一個(gè)前臺(tái)、可視、服務(wù)進(jìn)程。一般地有很多后臺(tái)進(jìn)程運(yùn)行著,因此它們保持在一個(gè)LRU(least recently used,即最近最少使用,如果您學(xué)過操作系統(tǒng)的話會(huì)覺得它很熟悉,跟內(nèi)存的頁面置換算法LRU一樣。)列表以確保最近使用最多的活動(dòng)的進(jìn)程最后被殺。

空進(jìn)程(Empty process):???????

? ? ? ?是一個(gè)沒有保持活躍的應(yīng)用程序組件的進(jìn)程。保持這個(gè)進(jìn)程可用的唯一原因是作為一個(gè)cache以提高下次啟動(dòng)組件的速度。系統(tǒng)進(jìn)程殺死這些進(jìn)程,以在進(jìn)程cache和潛在的內(nèi)核cache之間平衡整個(gè)系統(tǒng)資源。

總結(jié):

1、一個(gè)進(jìn)程的排名因?yàn)槠渌M(jìn)程依賴它而上升。一個(gè)進(jìn)程服務(wù)其它進(jìn)程,它的排名從不會(huì)比它服務(wù)的進(jìn)程低。例如,進(jìn)程A中的一個(gè)內(nèi)容提供者服務(wù)進(jìn)程B中的一個(gè)客戶,或者進(jìn)程A中的一個(gè)服務(wù)綁定到進(jìn)程B中的一個(gè)組件,進(jìn)程A總是被認(rèn)為比進(jìn)程B重要。 ?

2、因?yàn)橐粋€(gè)服務(wù)進(jìn)程排名比后臺(tái)活動(dòng)的進(jìn)程排名高,一個(gè)活動(dòng)啟動(dòng)一個(gè)服務(wù)來初始化一個(gè)長時(shí)間運(yùn)行操作,而不是簡單地衍生一個(gè)線程——特別是如果操作很可能會(huì)拖垮活動(dòng)(例如出現(xiàn)ANR)。這方面的例子是在后臺(tái)播放音樂和上傳相機(jī)拍攝的圖片到一個(gè)網(wǎng)站。使用服務(wù)保證操作至少有“服務(wù)進(jìn)程”的優(yōu)先級(jí),無論活動(dòng)發(fā)生什么情況。

3、Android修改了Linux內(nèi)核里標(biāo)準(zhǔn)的OOM Killer,取而代之是一個(gè)叫LowMemKiller的驅(qū)動(dòng),觸發(fā)Out Of Memory事件的不再是Linux內(nèi)核里的Notifier,而由Android系統(tǒng)進(jìn)程來驅(qū)動(dòng)。像我們前面說明的,在Android里負(fù)責(zé)管理進(jìn)程生成與Activity調(diào)用棧的會(huì)是這個(gè)系統(tǒng)進(jìn)程,這樣在遇到系統(tǒng)內(nèi)存不夠(可以直接通過查詢空閑內(nèi)存來得到)時(shí),就觸發(fā)Low Memory Killer驅(qū)動(dòng)來殺死進(jìn)程來釋放內(nèi)存。


知識(shí)點(diǎn)九:SandBox機(jī)制

描述:沙箱(sandbox)是為執(zhí)行中的程序提供隔離環(huán)境的一種安全機(jī)制。它通過嚴(yán)格控制執(zhí)行的程序所訪問的資源,以確保系統(tǒng)的安全。

? ? ? ? 在Android系統(tǒng)中,應(yīng)用(通常)都在一個(gè)獨(dú)立的沙箱中運(yùn)行,即每一個(gè)Android應(yīng)用程序都在它自己的進(jìn)程中運(yùn)行,都擁有一個(gè)獨(dú)立的Dalvik虛擬機(jī)實(shí)例。Dalvik經(jīng)過優(yōu)化,允許在有限的內(nèi)存中同時(shí)高效地運(yùn)行多個(gè)虛擬機(jī)的實(shí)例,并且每一個(gè)Dalvik應(yīng)用作為一個(gè)獨(dú)立的Linux進(jìn)程執(zhí)行。Android這種基于Linux的進(jìn)程“沙箱”機(jī)制,是整個(gè)安全設(shè)計(jì)的基礎(chǔ)之一。? ? ???

? ? ? ?Android從Linux繼承了已經(jīng)深入人心的類Unix進(jìn)程隔離機(jī)制與最小權(quán)限原則,同時(shí)結(jié)合移動(dòng)終端的具體應(yīng)用特點(diǎn),進(jìn)行了許多有益的改進(jìn)與提升。具體而言,進(jìn)程以隔離的用戶環(huán)境運(yùn)行,不能相互干擾,比如發(fā)送信號(hào)或者訪問其他進(jìn)程的內(nèi)存空間。 ??????

? ? ? ?因此,Android沙箱的核心機(jī)制基于以下幾個(gè)概念:?

1、標(biāo)準(zhǔn)的Linux進(jìn)程隔離?

2、大多數(shù)進(jìn)程擁有唯一的用戶ID(UID)?

3、嚴(yán)格限制文件系統(tǒng)權(quán)限。

應(yīng)用程序在獨(dú)立的進(jìn)程:???????

? ? ? ?應(yīng)用程序進(jìn)程之間,應(yīng)用程序與操作系統(tǒng)之間的安全性由Linux操作系統(tǒng)的標(biāo)準(zhǔn)進(jìn)程級(jí)安全機(jī)制實(shí)現(xiàn)。在默認(rèn)狀態(tài)下,應(yīng)用程序之間無法交互,運(yùn)行在進(jìn)程沙箱內(nèi)的應(yīng)用程序沒有被分配權(quán)限,無法訪問系統(tǒng)或資源。因此,無論是直接運(yùn)行于操作系統(tǒng)之上的應(yīng)用程序,還是運(yùn)行于Dalvik虛擬機(jī)的應(yīng)用程序都得到同樣的安全隔離與保護(hù),被限制在各自“沙箱”內(nèi)的應(yīng)用程序互不干擾,對(duì)系統(tǒng)與其他應(yīng)用程序的損害可降至最低。Android應(yīng)用程序的“沙箱”機(jī)制如下圖?1,互相不具備信任關(guān)系的應(yīng)用程序相互隔離,獨(dú)自運(yùn)行,箭頭訪問是禁止的。

應(yīng)用程序在同一個(gè)進(jìn)程(共享UID):????????

? ? ? 在很多情況下,源自同一開發(fā)者或同一開發(fā)機(jī)構(gòu)的應(yīng)用程序,相互間存在信任關(guān)系。Android系統(tǒng)提供一種所謂共享UID(SharedUserID)機(jī)制,使具備信任關(guān)系的應(yīng)用程序可以運(yùn)行于同一進(jìn)程空間。通常 ,這種信任關(guān)系由應(yīng)用程序的數(shù)字簽名確定,并且需要應(yīng)用程序在manifest文件中使用相同的UID。 ???????

? ? ? ?不同的應(yīng)用程序可以運(yùn)行在相同的進(jìn)程中。對(duì)于此方法,首先必須使用相同的私鑰簽署這些應(yīng)用程序,然后必須使用 manifest 文件給它們分配相同的 Linux 用戶 ID,這可以通過用相同的值/名定義 manifest 屬性?android:sharedUserId?來做到。通過sharedUserId,擁有同一個(gè)User id的多個(gè)APK安裝包可以配置成運(yùn)行在同一個(gè)進(jìn)程中.所以默認(rèn)就是可以互相訪問任意數(shù)據(jù). 也可以配置成運(yùn)行成不同的進(jìn)程, 同時(shí)可以訪問其他APK的數(shù)據(jù)目錄下的數(shù)據(jù)庫和文件.就像訪問本程序的數(shù)據(jù)一樣。這樣就為同一個(gè)機(jī)構(gòu)開發(fā)的不同App之間的數(shù)據(jù)共享,提供了便利。

應(yīng)用程序在同一個(gè)進(jìn)程(共享UID):

知識(shí)點(diǎn)十:進(jìn)程的?;钆c拉活

實(shí)現(xiàn)思想:

1.?;睿和ㄟ^提高進(jìn)程優(yōu)先級(jí),降低進(jìn)程被殺死的概率?

2.拉起:進(jìn)程被殺死后,進(jìn)行拉起

?;畹氖侄危?/p>

一:利用 Activity 提升權(quán)限:監(jiān)控手機(jī)鎖屏解鎖事件,在屏幕鎖屏?xí)r啟動(dòng)1個(gè)像素的 Activity,在用戶解鎖時(shí)將 Activity 銷毀掉。注意該 Activity 需設(shè)計(jì)成用戶無感知。通過該方案,可以使進(jìn)程的優(yōu)先級(jí)在屏幕鎖屏?xí)r間由4提升為最高優(yōu)先級(jí)1。?

二:利用 Notification 提升權(quán)限:Android 中 Service 的優(yōu)先級(jí)為4,通過 setForeground 接口可以將后臺(tái) Service 設(shè)置為前臺(tái) Service,使進(jìn)程的優(yōu)先級(jí)由4提升為2,從而使進(jìn)程的優(yōu)先級(jí)僅僅低于用戶當(dāng)前正在交互的進(jìn)程,與可見進(jìn)程優(yōu)先級(jí)一致,使進(jìn)程被殺死的概率大大降低。?

三:提升service優(yōu)先級(jí):在AndroidManifest.xml文件中對(duì)于intent-filter可以通過android:priority = "1000"這個(gè)屬性設(shè)置最高優(yōu)先級(jí),1000是最高值,如果數(shù)字越小則優(yōu)先級(jí)越低,同時(shí)適用于廣播。 ?

四:當(dāng)service運(yùn)行在低內(nèi)存的環(huán)境時(shí),將會(huì)kill掉一些存在的進(jìn)程。因此進(jìn)程的優(yōu)先級(jí)將會(huì)很重要,可以使用startForeground 將service放到前臺(tái)狀態(tài)。這樣在低內(nèi)存時(shí)被kill的幾率會(huì)低一些。?

五:Application加上Persistent屬性。

拉活的手段:

一:利用系統(tǒng)廣播拉活(注冊(cè)高頻率廣播接收器,喚起進(jìn)程),例如:開機(jī)廣播,網(wǎng)絡(luò)變化,文件掛載,屏幕亮滅,鎖屏解鎖,應(yīng)用安裝卸載。

二:雙進(jìn)程相互喚起。

三:onDestroy方法里重啟service:service +broadcast 方式,就是當(dāng)service走ondestory的時(shí)候,發(fā)送一個(gè)自定義的廣播,當(dāng)收到廣播的時(shí)候,重新啟動(dòng)service。

四:利用第三方應(yīng)用廣播拉活:通過反編譯第三方 Top 應(yīng)用,如:手機(jī)QQ、微信、支付寶、UC瀏覽器等,以及友盟、信鴿、個(gè)推等 SDK,找出它們外發(fā)的廣播,在應(yīng)用中進(jìn)行監(jiān)聽,這樣當(dāng)這些應(yīng)用發(fā)出廣播時(shí),就會(huì)將我們的應(yīng)用拉活。

五:利用系統(tǒng)Service機(jī)制拉活:將 Service 設(shè)置為 START_STICKY,利用系統(tǒng)機(jī)制在 Service 掛掉后自動(dòng)拉活。

六:利用Native進(jìn)程拉活:1、利用 Linux 中的 fork 機(jī)制創(chuàng)建 Native 進(jìn)程,在 Native 進(jìn)程中監(jiān)控主進(jìn)程的存活,當(dāng)主進(jìn)程掛掉后,在 Native 進(jìn)程中立即對(duì)主進(jìn)程進(jìn)行拉活。 2、在 Android 中所有進(jìn)程和系統(tǒng)組件的生命周期受 ActivityManagerService 的統(tǒng)一管理。而且,通過 Linux 的 fork 機(jī)制創(chuàng)建的進(jìn)程為純 Linux 進(jìn)程,其生命周期不受 Android 的管理。

七、利用 JobScheduler 機(jī)制拉活:Android5.0 以后系統(tǒng)對(duì) Native 進(jìn)程等加強(qiáng)了管理,Native 拉活方式失效。系統(tǒng)在 Android5.0 以上版本提供了 JobScheduler 接口,系統(tǒng)會(huì)定時(shí)調(diào)用該進(jìn)程以使應(yīng)用進(jìn)行一些邏輯操作。

八:利用賬號(hào)同步機(jī)制拉活:Android 系統(tǒng)的賬號(hào)同步機(jī)制會(huì)定期同步賬號(hào)進(jìn)行,該方案目的在于利用同步機(jī)制進(jìn)行進(jìn)程的拉活。

九:依靠第三方:根據(jù)終端不同,在小米手機(jī)(包括 MIUI)接入小米推送、華為手機(jī)接入華為推送;其他手機(jī)可以考慮接入騰訊信鴿或極光推送與小米推送做 A/B Test。


知識(shí)點(diǎn)十一:Jobscheduler使用

背景:Android 5.0系統(tǒng)以前,在處理一些特定情況下的任務(wù),或者是為了應(yīng)用的?;睿覀兺ǔJ鞘褂昧薙ervice常駐后臺(tái)來滿足我們的需求。當(dāng)達(dá)到某個(gè)條件時(shí)觸發(fā)該Service來進(jìn)行相應(yīng)任務(wù)的處理?;蛘邇H僅是為了我們自己的應(yīng)用不被系統(tǒng)回收銷毀。這樣做在滿足了自己應(yīng)用的需求的同時(shí)也消耗了部分硬件性能。對(duì)用戶的體驗(yàn)上,和Android系統(tǒng)環(huán)境上都有不利的影響。而且在其它地方,大多數(shù)開發(fā)者都認(rèn)為在后臺(tái)永駐進(jìn)程,是獲取用戶的隱私,是不合法的。然而在我國也許是因?yàn)殚_發(fā)商的需求大,迫切想要達(dá)到自己的目標(biāo),使用永駐的進(jìn)程可以完成用戶行為分析和推送等其它后臺(tái)的業(yè)務(wù)。因此在開發(fā)的模式上采取了極端的個(gè)體主義思想。 ???????Android 5.0系統(tǒng)以后,Google為了優(yōu)化Android系統(tǒng),提高使用流暢度以及延長電池續(xù)航,加入了在應(yīng)用后臺(tái)/鎖屏?xí)r,系統(tǒng)會(huì)回收應(yīng)用,同時(shí)自動(dòng)銷毀應(yīng)用拉起的Service的機(jī)制。同時(shí)為了滿足在特定條件下需要執(zhí)行某些任務(wù)的需求,google在全新一代操作系統(tǒng)上,采取了Job (jobservice & JobInfo)的方式,即每個(gè)需要后臺(tái)的業(yè)務(wù)處理為一個(gè)job,通過系統(tǒng)管理job,來提高資源的利用率,從而提高性能,節(jié)省電源。這樣又能滿足APP開發(fā)商的要求,又能滿足系統(tǒng)性能的要求。Jobscheduler由此應(yīng)運(yùn)而生。

適用場景:??????

? ?需要在Android設(shè)備滿足某種場合才需要去執(zhí)行處理數(shù)據(jù):?

一:應(yīng)用具有可以推遲的非面向用戶的工作(定期數(shù)據(jù)庫數(shù)據(jù)更新)?

二:應(yīng)用具有當(dāng)插入設(shè)備時(shí)希望優(yōu)先執(zhí)行的工作(充電時(shí)才希望執(zhí)行的工作備份數(shù)據(jù))?

三:需要訪問網(wǎng)絡(luò)或 Wi-Fi 連接時(shí)需要進(jìn)行的任務(wù)(如向服務(wù)器拉取內(nèi)置數(shù)據(jù))?

四:希望作為一個(gè)批次定期運(yùn)行的許多任務(wù)(s)

衍生應(yīng)用:

一:使用JobScheduler進(jìn)行開機(jī)自啟動(dòng)。?

二:Android服務(wù)?;?JobScheduler拉活。?

三:Android進(jìn)程?;畹囊话闾茁?。


知識(shí)點(diǎn)十二:Binder機(jī)制

描述:Binder基于Client-Server通信模式,傳輸過程只需一次拷貝,為發(fā)送端添加UID/PID身份,既支持實(shí)名Binder也支持匿名Binder,安全性高,簡單高效,再加上其面向?qū)ο蟮脑O(shè)計(jì)思想,獨(dú)特的接收緩存管理和線程池管理方式,成為Android進(jìn)程間通信的中流砥柱。

Binder機(jī)制的優(yōu)點(diǎn):

優(yōu)點(diǎn)詳解:

性能的角度:數(shù)據(jù)拷貝次數(shù):Binder數(shù)據(jù)拷貝只需要一次,而管道、消息隊(duì)列、Socket都需要2次,但共享內(nèi)存方式一次內(nèi)存拷貝都不需要;從性能角度看,Binder性能僅次于共享內(nèi)存。?

穩(wěn)定性的角度:Binder是基于C/S架構(gòu)的,簡單解釋下C/S架構(gòu),是指客戶端(Client)和服務(wù)端(Server)組成的架構(gòu),Client端有什么需求,直接發(fā)送給Server端去完成,架構(gòu)清晰明朗,Server端與Client端相對(duì)獨(dú)立,穩(wěn)定性較好;而共享內(nèi)存實(shí)現(xiàn)方式復(fù)雜,沒有客戶與服務(wù)端之別, 需要充分考慮到訪問臨界資源的并發(fā)同步問題,否則可能會(huì)出現(xiàn)死鎖等問題;從這穩(wěn)定性角度看,Binder架構(gòu)優(yōu)越于共享內(nèi)存。?

安全的角度:傳統(tǒng)Linux IPC的接收方無法獲得對(duì)方進(jìn)程可靠的UID/PID,從而無法鑒別對(duì)方身份,傳統(tǒng)IPC只能由用戶在數(shù)據(jù)包里填入U(xiǎn)ID/PID,這個(gè)標(biāo)記完全是在用戶空間控制的,沒有放在內(nèi)核空間,因此有被惡意篡改的可能;而Android作為一個(gè)開放的開源體系,擁有非常多的開發(fā)平臺(tái),App來源甚廣,因此手機(jī)的安全顯得額外重要;對(duì)于普通用戶,絕不希望從App商店下載偷窺隱射數(shù)據(jù)、后臺(tái)造成手機(jī)耗電等等問題,傳統(tǒng)Linux IPC無任何保護(hù)措施,完全由上層協(xié)議來確保。

Binder機(jī)制涉及到的四個(gè)角色:

Binder機(jī)制通信的過程描述:

Binder機(jī)制通信的過程圖解:

知識(shí)點(diǎn)十三:Android權(quán)限機(jī)制

背景:默認(rèn)情況下沒有任何應(yīng)用有權(quán)限去執(zhí)行對(duì)其他應(yīng)用、操作系統(tǒng)、用戶有不利影響的操作。這是一個(gè)核心的設(shè)計(jì)理念。記住這句話對(duì)后面的權(quán)限管理可以很好的理解。??????正是由于這樣的設(shè)計(jì)理念,默認(rèn)情況下應(yīng)用不能去讀寫用戶的私有數(shù)據(jù)(比如Email和Contacts),不能去讀寫其他App的文件,不能執(zhí)行網(wǎng)絡(luò)訪問,不能保持設(shè)備始終喚醒等等。

Security Architecture(安全體系結(jié)構(gòu)):???????

? ? ? ?因?yàn)槊恳粋€(gè)Android 應(yīng)用都是在一個(gè)進(jìn)程沙盒中運(yùn)行的,應(yīng)用必須明確分享的資源和數(shù)據(jù),通過申明需要的額外權(quán)限這種方式(這些額外權(quán)限不由基本沙盒提供)。應(yīng)用靜態(tài)的聲明這些權(quán)限(在Manifest里面),然后Android系統(tǒng)會(huì)請(qǐng)求用戶同意這些權(quán)限。 ???????

? ? ? ?Android應(yīng)用沙盒不依賴于創(chuàng)建應(yīng)用的技術(shù),特別的是Dalvik虛擬機(jī)并不是安全邊界的,所有的應(yīng)用都可以運(yùn)行native code(比如參見NDK),所有類型的應(yīng)用-Java,native,hybird,都是以同樣的方式封裝在沙盒內(nèi)并且相互之間是同樣的安全等級(jí)。

Application signing(應(yīng)用簽名):???????

? ? ? ?所有的Apk文件都必須由他的開發(fā)者使用私有的簽名證書簽名,這個(gè)證書是開發(fā)者身份的唯一標(biāo)識(shí),這個(gè)證書是由開發(fā)者自己生成的開放式的證書,用于自己簽名應(yīng)用。證書的目的是標(biāo)識(shí)應(yīng)用的身份,這樣可以讓系統(tǒng)知道是該允許還是拒絕應(yīng)用訪問簽名級(jí)別的權(quán)限(signature-level permissions),以及允許還是拒絕應(yīng)用所請(qǐng)求的給予相同Linux身份來作為不同的應(yīng)用。

User IDs and File Access(用戶ID和文件訪問):???????

? ? ? ?在安裝一個(gè)app package的時(shí)候,android系統(tǒng)會(huì)給每一個(gè)package一個(gè)獨(dú)立的Linux user ID。這個(gè)User ID在這個(gè)應(yīng)用在當(dāng)前設(shè)備的生命周期內(nèi)都是固定不變的,在不同的設(shè)備,相同的package的用戶ID可能各不相同,但可以確定的是在一臺(tái)設(shè)備上一個(gè)package的用戶ID是固定不變的。 ???????

? ? ? ?因?yàn)榘踩珗?zhí)行是發(fā)生在進(jìn)程層面的,兩個(gè)不同的package不能運(yùn)行在相同的進(jìn)程中,他們會(huì)被作為不同的Linux用戶來運(yùn)行。 ???????

? ? ? ?但是你可以在manifest中使用sharedUserId屬性來指定不同的package有相同的User ID,這樣這兩個(gè)不同的package將會(huì)被視為相同的APP,會(huì)有相同的User ID和文件權(quán)限。 ??????

? ? ? ?當(dāng)然為了保證安全,只有兩個(gè)APP簽名一致且申明了相同的sharedUserId才會(huì)被給予相同的User ID。


七:Android操作系統(tǒng)的演進(jìn)

? ? ? ?先來看看Android系統(tǒng)的發(fā)展過程,從2008年發(fā)布Android 1.0系統(tǒng),直到2019年即將發(fā)布Android 10.0系統(tǒng),下面列舉些重要的時(shí)間節(jié)點(diǎn)。

2003年10月,Andy Rubin團(tuán)隊(duì)創(chuàng)辦Android公司。?

2005年8月,谷歌收購Android公司,Andy Rubin擔(dān)任谷歌工程部副總裁繼續(xù)負(fù)責(zé)Android項(xiàng)目。?

2008年9月,谷歌正式發(fā)布Android 1.0系統(tǒng)。?

2011年1月,Android系統(tǒng)設(shè)備的用戶總數(shù)達(dá)到了1.35億,成為智能手機(jī)領(lǐng)域占有量第一的系統(tǒng)。?

2011年8月,Android手機(jī)占據(jù)全球智能機(jī)市場48%份額,并在亞太地區(qū)市場占據(jù)統(tǒng)治地位,終結(jié)了Symbian系統(tǒng)的霸主地位,躍居全球第一。 2012年1月,谷歌Android Market已有10萬開發(fā)者,推出超過40萬應(yīng)用。?

2013年11月,Android 4.4正式發(fā)布,系統(tǒng)更智能、UI更現(xiàn)代。?

2013年到2018年,這個(gè)階段安卓進(jìn)入飛速發(fā)展期,被升級(jí)的有攝像頭、內(nèi)存、機(jī)身、芯片等,原來的3.5寸小屏已退出歷史舞臺(tái),全面屏、劉海屏、水滴屏已成為當(dāng)下主流屏幕方案。

一:從Android 1.0發(fā)展到Android 4.0,系統(tǒng)各項(xiàng)功能和特性迭代到一個(gè)較完善的階段;?

二:Android 4.1系統(tǒng),Google開展了黃油計(jì)劃(Project Butter),為了讓Android系統(tǒng)擺脫UI交互上的嚴(yán)重滯后感,希望能像“黃油”一樣順滑。 ????????核心原理是系統(tǒng)框架中的渲染和動(dòng)畫統(tǒng)一采用垂直同步技術(shù)(VSYNC),以及三重緩沖技術(shù)(Triple Buffer),讓滑動(dòng)、翻頁等操作更加一致與順滑。 ?

三:Android 4.4系統(tǒng),Google開展了瘦身計(jì)劃(Project Svelte),力求降低安卓系統(tǒng)的內(nèi)存使用,解決低端機(jī)型升級(jí)難的問題,讓Android 4.4可正常運(yùn)行在所有Android手機(jī),從而減少安卓系統(tǒng)繼續(xù)碎片化。UI設(shè)計(jì)上,支持新的“沉浸式模式”,用戶界面由過去的黑色與藍(lán)色為主的色調(diào)轉(zhuǎn)向帶有透明度的淺色系,視覺語言變得更加明亮與現(xiàn)代化。

四:Android 5.0系統(tǒng),Google開展了伏特計(jì)劃(Project Volta),力求提升續(xù)航能力,這方面Google落后于業(yè)界廠商,廠商直面用戶對(duì)續(xù)航尤為迫切,往往系統(tǒng)資源管控更為嚴(yán)格。另外,系統(tǒng)采用全新的ART,拋棄Dalvik虛擬機(jī),大幅提升運(yùn)行效率。UI設(shè)計(jì)上,使用全新的扁平化Material Design設(shè)計(jì)風(fēng)格,更加清新與質(zhì)感的設(shè)計(jì),統(tǒng)一Android設(shè)備的外觀和使用體驗(yàn)。?

五:Android 6.0系統(tǒng),Google引入新的運(yùn)行時(shí)權(quán)限,讓用戶能夠更好地了解和控制權(quán)限;引入了Doze模式,進(jìn)一步提升電池續(xù)航能力。UI設(shè)計(jì)上,新增夜間模式,大幅改進(jìn)通知欄,讓通知更簡潔。 ?

六:Android 7.0系統(tǒng),引入新的JIT編譯器,對(duì)AOT編譯器的補(bǔ)充,可節(jié)省存儲(chǔ)空間和加快更新速度;進(jìn)一步優(yōu)化Doze喚醒機(jī)制;UI設(shè)計(jì)上,支持分屏功能; ?

七:Android 8.0系統(tǒng),Google開展了計(jì)劃(Project Treble),重新架構(gòu)Android,將安卓系統(tǒng)框架與Vendor層解耦,力求徹底解決安卓碎片化這一老大難的問題,這是安卓系統(tǒng)架構(gòu)最大的變化。系統(tǒng)層面加強(qiáng)對(duì)后臺(tái)服務(wù)、廣播、位置的管控限制。UI設(shè)計(jì)上,改進(jìn)通知欄,智能文本選擇和自動(dòng)填充功能。

八:Android 9.0系統(tǒng),引入神經(jīng)網(wǎng)絡(luò)API,采用機(jī)器學(xué)習(xí)的思路來預(yù)測用戶使用習(xí)慣來做省電優(yōu)化,繼續(xù)強(qiáng)化Treble計(jì)劃;文件系統(tǒng)(sdcardf/F2FS)持續(xù)提升;私有API的限制進(jìn)一步規(guī)范化Android生態(tài),強(qiáng)化隱私和安全,硬件安全性模塊以及統(tǒng)一生物識(shí)別身份驗(yàn)證界面。 UI設(shè)計(jì)上,新的手勢(shì)導(dǎo)航,加強(qiáng)支持劉海屏,UI搜索界面使用到機(jī)器學(xué)習(xí),AI正在逐步強(qiáng)化Android系統(tǒng)。?

九:Android 10.0系統(tǒng),Google開展了主線計(jì)劃(Project Mainline),相關(guān)模塊(Modules)不允許廠商直接修改,只能由Google應(yīng)用商店來更新升級(jí),強(qiáng)化用戶隱私、系統(tǒng)安全與兼容性。支持臉部生物識(shí)別。

系統(tǒng)演進(jìn)趨勢(shì):???????

? ? ? ?每個(gè)Android大版本的更新迭代前行,歷經(jīng)10余年,在用戶體驗(yàn)、流暢性、續(xù)航、安全、隱私、機(jī)器學(xué)習(xí)等方面都取得較大的改進(jìn)。圖中是每個(gè)大版本中最具代表性的特征標(biāo)記在圖中,并不代表著該版本全部特征,同樣專項(xiàng)計(jì)劃也不是只在某一個(gè)版本執(zhí)行,比如續(xù)航和性能優(yōu)化,每一個(gè)版本都在持續(xù)改進(jìn)中,Treble計(jì)劃也一直在迭代至今。


八:擴(kuò)展閱讀

1、https://blog.csdn.net/qq_35114086/article/details/52614740(Android系統(tǒng)架構(gòu)的詳細(xì)解析——很全面)?

2、https://www.cnblogs.com/hejing-swust/articles/7821968.html(Android系統(tǒng)和linux內(nèi)核的關(guān)系詳解)?

3、https://blog.csdn.net/itachi85/article/details/54695046/(Android系統(tǒng)架構(gòu)與系統(tǒng)源碼目錄)

4、https://www.jiangshuaijie.com/androidyuan-ma/(Android系統(tǒng)源碼目錄解析)?

5、https://blog.csdn.net/yippeelyl/article/details/77076085(Android的5個(gè)進(jìn)程等級(jí))?

6、https://blog.csdn.net/ccjhdopc/article/details/52893738(Android 應(yīng)用程序啟動(dòng)過程分析)?

7、https://blog.csdn.net/lpjishu/article/details/50781415(Android系統(tǒng)服務(wù)詳解-android學(xué)習(xí)之旅)?

8、http://www.itdecent.cn/p/38859f881888(Android:JNI 與 NDK到底是什么?)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容