一、系統架構:
一)、系統分層:(由下向上)【如圖】
1、安卓系統分為四層,分別是Linux內核層、Libraries層、FrameWork層,以及Applications層;
其中Linux內核層包含了Linux內核和各種驅動;
Libraries層包含各種類庫(動態庫(也叫共享庫)、android運行時庫、Dalvik虛擬機),編程語言主要為C或C++
FrameWork層大部分使用java語言編寫,是android平台上Java世界的基石
Applications層是應用層,我們在這一層進行開發,使用java語音編寫
2、Dalvik VM和傳統JVM的區別:
傳統的JVM:編寫.java文件 à 編譯為.class文件 à 打包成.jar文件
Dalvik VM: 編寫.java文件 à 編譯為.class文件 à 打包成.dex文件 à 打包成.apk文件(通過dx工具)
將所有的類整合到一個文件中,提高了效率。更適合在手機上運行
1、Linux內核層[LINUX KERNEL]:
包含Linux內核和驅動模塊(比如USB、Camera、藍牙等)。
Android2.2(代號Froyo)基於Linux內核2.6版本。
2、Libraries層[LIBRARIES]:
這一層提供動態庫(也叫共享庫)、android運行時庫、Dalvik虛擬機等。
編程語言主要為C或C++,所以可以簡單的看成Native層。
3、FrameWork層[APPLICATION FRAMEWORK]:
這一層大部分用java語言編寫,它是android平台上Java世界的基石。
4、Applications層[APPLICATION]:應用層
如圖所示:
系統分層的圖整體簡化為下面的一張圖,對應如下:
FrameWork層 --------à Java世界
Libraries層 --------à Native世界
Linux內核層 --------à Linux OS
Java世界和Native世界間的通信是通過JNI層
JNI層和Native世界都可以直接調用系統底層
二)、系統編譯:
1、主要步驟:系統環境的准備,下載源碼、編譯源碼、輸出結果:
目前系統的編譯環境只支持Ubuntu 以及 Mac OS 兩種操作系統,磁盤的控件要足夠大
在下載源碼的時候,由於Android源碼使用Git進行管理,需要下載一些工具,如apt-get install git-core curl
源碼下載好后,進行編譯:首先搭建環境,部署JDK(不同的源碼編譯時需要的JDK版本不同,如2.2需要JDK5,2.3需要1.6),
然后設置編譯環境:使用. build/envsetup.sh腳本;選擇編譯目標(可以根據自己需要的版本進行不同的搭配)
最后通過make –j4的命令進行編譯。(make是編譯的函數即命令,j4指的是cpu處理器的核數:單核的是j4 x i;雙核的是j8)
最后將編譯好的結果進行輸出:所有的編譯產物都位於 /out 目錄下
2、編譯流程圖
二、系統的啟動:
通過Linux內核將Linux系統中用戶空間的第一個進程init啟動起來,這是安卓世界第一個被啟動的進程;
然后在init中會加載init.rc的配置文件,並開啟系統的守護進程(守護media(多媒體的裝載)和孵化器zygote(Java世界的開啟)),其實此時調試橋的守護進程也被開啟起來了;
然后會處理一些動作執行,在app_main.cpp中會將Zygote孵化器(Zygote是整個java世界的基礎,整個安卓世界中(包括framework和app等apk)都是由孵化器啟動的)啟動起來:
在app_main中,會調用AppRuntime的start方法開啟AppRuntime,其實開啟的是其父類AndroidRuntime的start方法被調用,zygote由此就被調用了,此時Native層的右上角有一塊區域即ANDROID RUNTIME就啟動起來了;
與此同時,AppRuntime會調用ZygoteInit的main方法啟動ZygoteInit(整個的APPLICATION 和FRAMEWORK都會由ZygoteInit帶起來的,JNI也被啟動起來):
在ZygoteInit中會調用SystemServer這個類,在SystemServer的main方法中啟動init1()方法,將system_init.cpp開啟起來,在init1()方法中,將整個Native世界(即LIBRARIES層)開啟起來了
然后在system_init.cpp會調用SystemServer的init2()方法開啟ServerThread,通過ServerThread將framework層開啟起來(所有的就全部開啟起來了),即java世界(APPLICATION FRAMEWORK)就被啟動了;此時ActivityManager,WindowManager,PackageManager(最主要,所有的清單文件及apk都有它管理)等等framework層全部開啟起來
一)安卓系統的總體啟動順序:
1、通過LINUX內核,將init進程啟動起來(是Linux系統中用戶空間的第一個進程)
2、將ANDROID RUNTIME這一塊的內容啟動完畢
3、分為兩步分別啟動LIBRARIES(即Native世界)和APPLICATION FRAMEWORK(即java世界)
1)先啟動LIBRARIES(即Native世界)
2)后啟動APPLICATION FRAMEWORK(即java世界)【ActivityManager,WindowManager,電源管理等等】
二)具體啟動流程
一)、啟動流程:
1、init進程:——安卓世界第一個被啟動的進程
加載一堆配置文件,核心加載的init.rc配置文件,其中包含了孵化器和守護進程都被開啟了
1)、啟動服務:開啟ServerManager
守護進程啟動(Daemon Process):/system/bin/servicemanager
守護的是:
①、Java世界的開啟:onrestart restart zygote
②、多媒體的裝載:onrestart restart media
@、adbd的守護也被開啟起來了,即調試橋的守護進程也被開啟起來了
2)、啟動孵化器Zygote
在app_main中啟動孵化器Zygote,整個安卓世界中(包括framework和app等apk)都是由孵化器啟動的
【此時虛擬機還沒開啟起來,只是配置了一些vm的參數】
3、app_main:——開啟孵化器
app_main中,調用AppRuntime的start方法,將Native層的右上角有一塊區域,即ANDROID RUNTIME啟動起來
其中的start方法實際是其父類AndroidRuntime的start方法
【此時VM虛擬機被開啟起來了,通過start方法開啟,在AndroidRuntime中並設置了默認的內存大小16M】
【注冊JNI,並啟動孵化器Zygote】
4、ZygoteInit開啟
AppRuntime被啟動后,會調用ZygoteInit的main方法,啟動ZygoteInit;
然后,整個的APPLICATION 和FRAMEWORK都會由ZygoteInit帶起來的
5、SystemServer啟動:
ZygoteInit調用SystemServer這個類,在SystemServer的main方法中啟動init1()方法,將system_init.cpp開啟起來
在init1()方法中,將整個Native世界開啟起來了
6、ServerThread啟動(開啟framework層)
調用SystemServer的init2()方法開啟ServerThread,通過ServerThread將framework層開啟起來(所有的就全部開啟起來了)
此時ActivityManager,WindowManager,PackageManager(最主要,所有的清單文件及apk都有它管理)等等framework層全部開啟起來
二)、具體介紹:
1、啟動入口:init進程
@、源碼位置:/system/core/init/init.c
@、進程入口:main方法
1)創建文件夾,掛載設備【通過mkdir的命令創建,掛載一些系統設備后】
2)重定向輸入輸出,如錯誤信息輸出【設置了一些輸入輸出的處理】
3)設置日志輸出【一些系統的日志】
4)init.rc系統啟動的配置文件【加載了相關的信息,不同版本的手機所特有的配置信息】
①、文件位置:/system/core/rootdir
②、守護進程啟動(Daemon Process):/system/bin/servicemanager
守護的是
Java世界的開啟:onrestart restart zygote
多媒體的裝載:onrestart restart media
adbd守護也被開啟起來了,即調試橋(adb[Android Debug Bridge])的守護進程(adbd[Android Debug Bridge Daemon])也被開啟起來了
③、啟動Zygote——app_main.cpp【Zygote是整個java世界的基礎】
當編譯之后,在system/bin/app_process下會有孵化器的啟動Xzygote
守護進程被開啟之后,緊接着Zygote也被啟動起來了
5)解析和當前設備相關的配置信息(/init.%s.rc)
Tips:
當解析完init.rc和設備配置信息后會獲取到一系列Action
Init將動作的執行划分為四個階段(優先級由大到小):
early-init :初期
Init :初始化階段
early-boot :系統啟動的初期
boot :系統啟動
6)處理動作執行:這個階段Zygote將被啟動
7)無限循環階段,等待一些事情發生
2、Zygote簡介:
@、Zygote啟動:app_main.cpp
1)Zygote簡介:
①、本身為Native的應用程序
②、由init進程通過init.rc加載
2)功能分析:
①、Main方法中AppRuntime.start(),工作由父類AndroidRuntime來完成
②、在AndroidRuntime中開啟了如下內容:
@startVM——開啟虛擬機(查看堆內存設置):默認16M【】
@注冊JNI函數【此時還在Native層,需要將連接java和c的橋(即JNI)搭建好】
@啟動“com.android.internal.os.ZygoteInit”的main方法
【系統級別的包(由runtime的start方法開啟的這個包)】
start方法實際是其父類AndroidRuntime的
@進入java世界的入口
3、ServiceThread的簡介:(java世界所做的事情)
1)preloadClasses();:預加載class
讀取一個preloaded-classes的配置文件
此文件的內容非常多,這就是安卓系統啟動慢的原因之一
此時會有一個垃圾回收的操作gc(),將無用的回收掉
2)ZygoteInit在main方法中利用JNI開啟com.android.server.SystemServer
3)啟動system_init.cpp處理Native層的服務
4)然后調用SystemServer的init2()
5)啟動ServiceThread,啟動android服務
6)Launcher啟動
三、開機時的時間消耗:
1、ZygoteInit.main()中會預加載類
目錄:framework/base/preload-class
ZygoteInit.main()會加載很多的類,將近1800多個(安卓2.3的)
2、開機時會對系統所有的apk進行掃描
需要將所有的應用展現給用戶,就需要對apk進行掃描,掃描所有的包
data目錄下有個apk的包
system目錄下有個apk的包
framework目錄下也有相關的包
3、SystemServer創建的那些Service