Android核心服務解析篇(二)——Android原始碼結構分析
獲得Android原始碼後,我們來分析原始碼結構。原始碼的全部工程分為如下三個部分。
①Core Project:核心工程部分,這是建立Android系統的基礎,儲存在根目錄的各個資料夾中。
②External Project:擴充套件工程部分,可以使其他開源專案具有擴充套件功能,儲存在external資料夾中。
③Package:包部分,提供了Android的應用程式,內容提供者,輸入法和服務,儲存在package資料夾中。
在獲取的Android4.3原始碼目錄中,包含了原始Android的目標機程式碼,主機編譯工具和模擬環境。解壓縮下載的Android4.3原始碼包後,第一級別目錄結構的具體說明如下表所示:
根目錄 | 描述 |
abi | abi相關程式碼,應用程式二進位制介面 |
bionic | bionic C庫 |
bootable | 啟動引導相關程式碼 |
build | 存放系統編譯規則及generic等基礎開發配置包 |
cts | Android相容性測試套件標準 |
dalvik | dalvik Java虛擬機器 |
development | 應用程式開發相關程式碼 |
device | 裝置相關程式碼 |
docs | 介紹開源的相關文件 |
external | Android使用的一些開源的模組 |
frameworks | 核心框架——Java及C++語言,是Android應用程式的框架 |
gdk | 即時通訊模組 |
hardware | 主要是硬體適配層HAL程式碼 |
kernel | Linux的核心檔案 |
libcore | 核心庫相關 |
libnativehelper | 是Support functions for Android's class libraries的別名,表示動態庫,是實現JNI庫的基礎 |
ndk | ndk相關程式碼。Android NDK(Android Native Development Kit)是一系列的開發工具,允許程式開發人員在Android應用程式中嵌入C/C++語言編寫的非託管程式碼 |
out | 編譯完成後的程式碼輸出在此目錄 |
packages | 應用程式包 |
pdk | Plug Development Kit的縮寫,是本地開發套件 |
prebuilts | x86和ARM架構下預編譯的一些資源 |
sdk | SDK及模擬器 |
system | 檔案系統和應用及元件,是用C語言實現的 |
tools | 工具資料夾 |
vendor | 廠商定製程式碼 |
Makefile | 全域性的Makefile |
資料夾目錄如下:
1.Android原始碼的目錄結構
當下載好Android原始碼後,可以看到,第一級目錄有18個資料夾和一個Makefile檔案,如果是編譯後的原始碼目錄,會增加一個out資料夾,用來存放編譯產生的檔案,下面具體來分析一下這些目錄各自的作用:
|——abi//應用程式的二進位制介面
|——bionic//Android基礎C庫的原始碼
|——bootable //系統啟動器的原始碼
|——build//編譯和配置系統所需要的配置檔案和指令碼檔案
|——cts//Android相容性測試標準
|——dalvik//Android虛擬機器原始碼
|——development //程式開發的模板和工具
|——device//裝置相關程式碼
|——docs//開源的相關文件
|——external //Android使用的第三方開源庫的原始碼
|——frameworks //應用程式框架原始碼
|——gdk//即時通訊模組
|——hardware //硬體抽象層原始碼
|——libcore//相關核心庫的程式碼
|——libnativehelper //動態庫
|——ndk//NDK開發環境
|——packages //應用程式包
|——pdk//本地開發套件
|——prebuilt //x86和ARM架構下預編譯的一些資源
|——sdk//SDK和模擬器相關程式碼
|——system//檔案系統,應用和元件
|——Makefile //系統編譯指令碼
通過上面對原始碼根目錄中的每個資料夾的介紹,可以看出原始碼是按照功能進行分類的,整個Android原始碼分為系統程式碼,工具,文件,開發環境,虛擬機器,配置指令碼和編譯指令碼等類別。
2.應用程式
在Android原始碼中,應用程式部分的功能是實現UI介面,開發人員基於SDK開發的APK包便屬於應用程式層。應用程式層在Android系統中處於最頂層,Android 4.3原始碼結構中的packages目錄用來實現系統的應用程式,此目錄的具體結構如下所示:
packages /
|——apps//應用程式庫
|——|——BasicSmsReceiver//基礎簡訊接收
|——|——Bluetooth//藍芽
|——|——Browser//瀏覽器
|——|——Calculator//計算器
|——|——Calendar//日曆
|——|——Camera//照相機
|——|——CellBroadcastReceiver//單元廣播接收
|——|——CertInstaller//被呼叫的包,在Android中安裝數字簽名
|——|——Contacts//聯絡人
|——|——DeskClock//桌面時鐘
|——|——Email//電子郵件
|——|——Exchange//Exchange服務
|——|——Gallery//相簿
|——|——Gallery2//相簿2
|——|——HTMLViewer//HTML檢視器
|——|——KeyChain//密碼管理
|——|——Launcher2 //啟動器
|——|——Mms//彩信
|——|——Music//音樂
|——|——MusicFX//音訊增強
|——|——Nfc//近場通訊
|——|——PackageInstaller//包安裝器
|——|——Phone//電話
|——|——Protips//主螢幕提示
|——|——Provision//引導設定
|——|——QuickSearchBox//快速搜尋框
|——|——Settings//設定
|——|——SoundRecorder//錄音機
|——|——SpareParts//系統設定
|——|——SpeechRecorder//錄音程式
|——|——Stk//sim卡相關
|——|——Tag//標籤
|——|——VideoEditor//視訊編輯
|——|——VoiceDialer//語音編號
|——experimental//非官方的應用程式
|——|——BugReportSender//Bug的報告程式
|——|——Bummer
|——|——CameraPreviewTest//照相機預覽測試程式
|——|——DreaamTheater
|——|——ExampleImsFramework
|——|——LoaderApp
|——|——NotificationLog
|——|——NotificationShowcase
|——|——procstatlog
|——|——RpcPerformance
|——|——StrictModeTest
|——inputmethods//輸入法
|——|——LatinIME//拉丁文輸入法
|——|——OpenWnn//OpenWnn輸入法
|——|——PinyinIME//拼音輸入法
|——providers//提供器
|——|——ApplicationsProvider//應用程式提供器,提供應用程式所需的介面
|——|——CalendarProvider//日曆提供器
|——|——ContactsProvider//聯絡人提供器
|——|——DownloadProvider//下載管理提供器
|——|——DrmProvider//資料庫相關
|——|——GoogleContactsProvider//Google聯絡人提供器
|——|——MediaProvider//媒體提供器
|——|——TelephonyProvider//彩信提供器
|——|——UserDictionaryProvider//使用者字典提供器
|——screensavers//螢幕保護
|——|——Basic//基本螢幕保護
|——|——PhotoTable//照片方格
|——|——WebView //網頁
|——wallpapers//牆紙
|——|——Basic//系統內建牆紙
|——|——Galaxy4//S4內建牆紙
|——|——HoloSpiral//手槍皮套牆紙
|——|——LivePicker
|——|——MagicSmoke
|——|——MusicVisualization
|——|——NoiseField
|——|——PhaseBeam
通過上面的目錄結構可以看出,在packages目錄中包含了應用程式相關的包或者資原始檔,不但包括系統自帶的應用程式,也包括第三方開發的應用程式和螢幕保護和牆紙等應用。
3.應用程式框架
應用程式框架是Android系統中的核心部分,也就是SDK部分,它會提供介面給應用程式使用,同時應用程式框架又會與系統服務,系統程式庫,硬體抽象層的關聯,所以其作用十分重大,應用程式框架的實現程式碼大部分都在/frameworks/base和/frameworks/av目錄下。
frameworks/base的目錄結構如下所示:
frameworks/base
|——api//全是XML檔案,定義了API
|——cmds//Android中的重要命令(am,app_proce等)
|——core//核心庫
|——data//聲音字型等資料檔案
|——docs//文件
|——drm//數字版權管理
|——graphics //圖形影象
|——icu4j//用於解決國際化問題
|——include//標頭檔案
|——keystore //數字簽名證書相關
|——libs//庫
|——location //地理位置
|——media//多媒體
|——native//本地庫
|——nfc-extras //NFC相關
|——obex//藍芽傳輸
|——opengl//OpenGL相關
|——packages //設定,TTS,VPN程式
|——policy//鎖屏介面相關
|——sax//XML解析器
|——services //Android服務
|——telephony //電話相關
|——test-runner //測試相關
|——tests//測試相關
|——tools//工具
|——voip//可視通話
|——wifi//無線網路
以上這些檔案包含了應用程式框架層的大部分程式碼,正是這些目錄下的檔案構成了Android的應用程式框架層,暴露出介面給應用程式呼叫,同時銜接系統程式庫和硬體抽象層,形成一個由上至下的呼叫過程。
4.系統服務
Android應用程式框架層的大部分實現程式碼被儲存在/frameworks/base目錄下,其實在這個目錄中還有一個名為service的目錄,裡面的程式碼用於實現Android系統服務,其目錄結構如下所示:
frameworks/base/services
|——common_time //日期時間相關的服務
|——input//輸入系統服務
|——java//其他重要服務的Java層
|——jni//其他重要服務的JNI層
|——tests//測試相關
其中java和jni兩個目錄分別是一些其他的服務的Java層和JNI層實現,java目錄下的目錄結構以及其他Android系統服務的相關說明如下所示:
frameworks/base/services/java/com/android/server
|——accessibility
|——am
|——connectivity
|——display
|——dreams
|——drm
|——input
|——location
|——net
|——pm
|——power
|——updates
|——usb
\——wm
|——AlarmManagerService.java//鬧鐘服務
|——AppWidgetService.java//應用程式小工具服務
|——AppWidgetServiceImpl.java
|——AttributeCache.java
\——BackupManagerService.java//備份服務
|——BatteryService.java//電池相關服務
|——BluetoothManagerService.java//藍芽
|——BootReceiver.java
|——BrickReceiver.java
|——CertBlacklister.java
|——ClipboardService.java
|——CommonTimeManagementService.java//時間管理服務
|——ConnectivityService.java
|——CountryDetectorService.java
|——DevicePolicyManagerService.java
|——DeviceStorageMonitorService.java//裝置儲存器監聽服務
|——DiskStatsService.java//磁碟狀態服務
|——DockObserver.java//底座監視服務
|——DropBoxManagerService.java
|——EntropyMixer.java
|——EventLogTags.logtags
|——INativeDaemonConnectorCallbacks.java
|——InputMethodManagerService.java//輸入法管理服務
|——IntentResolver.java
|——IntentResolverOld.java
|——LightsService.java
|——LocationManagerService.java//地理位置服務
|——MasterClearReceiver.java
|——MountService.java//掛載服務
|——NativeDaemonConnector.java
|——NativeDaemonConnectorException.java
|——NativeDaemonEvent.java
|——NetworkManagementService.java//網路管理服務
|——NetworkTimeUpdateService.java
|——NotificationManagerService.java//通知服務
|——NsdService.java
|——PackageManagerBackupAgent.java
|——PreferredComponent.java
|——ProcessMap.java
|——RandomBlock.java
|——RecognitionManagerService.java
|——SamplingProfilerService.java
|——SerialService.java//NFC相關
|——ServiceWatcher.java
|——ShutdownActivity.java
|——StatusBarManagerService.java//狀態列管理服務
|——SystemBackupAgent.java
|——SystemService.java
|——TelephonyRegistry.java
|——TextServicesManagerService.java
|——ThrottleService.java
|——TwilightCalculator.java
|——TwilightService.java
|——UiModeManagerService.java
|——UpdateLockService.java//鎖屏更新服務
|——VibratorService.java//震動服務
|——WallpaperManagerService.java//桌布服務
|——Watchdog.java//看門狗
|——WifiService.java//無線網路服務
|——WiredAccessoryManager.java//無線裝置管理服務
從上面的資料夾和檔案可以看出,Android中涉及的服務種類有:介面,網路,電話等核心模組,這些專屬服務是系統級別的服務,這些系統服務一般都會在Android系統啟動的時候載入,在系統關閉的時候結束,受到系統的管理,應用程式並沒有權力去開啟或者關閉,它們會隨著系統的執行一直在後臺執行,供應用程式和其他元件來使用。
另外,在framework/av/目錄下面有一個services目錄,在此目錄中存放的是音訊和照相機的服務的實現程式碼,此目錄的具體結構如下所示:
frameworks/av/services
|——audioflinger//音訊管理服務
|——camera//照相機的管理服務
av/services目錄主要用來支援Android系統中的音訊和照相機服務。
5.系統程式庫
Android4.3程式庫的型別非常多,功能也非常強大。在接下來的內容中,將簡要講解Android4.3原始碼中的一些常用並且重要的系統程式庫的知識。
㈠系統C庫
Android系統採用的是一個從BSD繼承而來的標準的系統函式庫bionic,在原始碼根目錄下有這個資料夾,其目錄結構如下所示:
bionic/
|——libc//C庫
|——libdl//動態連結庫相關
|——libm//數學庫
|——libstdc++ //C++實現庫
|——libthread_db //執行緒庫
|——linker//聯結器相關
|——test//測試相關
㈡媒體庫
Android中的媒體庫在2.3版之前是由OpenCore實現的,2.3版之後Stragefright被替換了,OpenCore成為新的多媒體的實現庫。同時Android自帶了一些音視訊的管理庫,用於管理多媒體的錄製,播放,編碼和解碼等功能。
Android的多媒體程式庫的實現程式碼主要在/frameworks/av/media目錄中,其目錄結構如下:
frameworks/av/media/
|——common_time //時間相關
|——libeffects //多媒體效果
|——libmedia //多媒體錄製,播放
|——libmedia_native //裡面只有一個Android。迥,用來編譯native檔案
|——libmediaplayerservice//多媒體播放服務的實現庫
|——libstagefright //Stagefright的實現庫
|——mediaserver //跨程序多媒體服務
|——mtp//MTP協議的實現(媒體傳輸協議)
㈢圖層顯示庫
Android中的圖層顯示庫主要負責對顯示子系統的管理,負責圖層的渲染,疊加,繪製等功能,提供了2D和3D圖層的無縫融合,是整個Android系統顯示的“大腦中樞”,其程式碼在/frameworks/native/services/surfaceflinger/目錄下,其目錄結構如下所示:
frameworks/native/services/surfaceflinger/
|——DisplayHardware//顯示底層相關
|——tests//測試
|——Android.mk//MakeFile檔案
|——Barrier.h
|——Client.cpp//顯示的客戶端實現檔案
|——Client.h
|——clz.cpp
|——clz.h
|——DdmConnection.cpp
|——DdmConnection.h
|——DisplayDevice.cpp//顯示裝置相關
|——DisplayDevice.h
|——EventThread.cpp//訊息執行緒
|——EventThread.h
|——GLExtensions.cpp//OpenGL擴充套件
|——GLExtensions.h
|——Layer.cpp//圖層相關
|——Layer.h
|——LayerBase.cpp//圖層基類
|——LayerBase.h
|——LayerDim.cpp//圖層相關
|——LayerDim.h
|——LayerScreenshot.cpp//圖層相關
|——LayerScreenshot.h
|——MessageQueue.cpp//訊息佇列
|——MessageQueue.h
|——MODULE_LICENSE_APACHE2//證書
|——SurfaceFlinger.cpp//圖層管理者,圖層管理的核心類
|——SurfaceFlinger.h
|——SurfaceTextureLayer.cpp//文字圖層
|——SurfaceTextureLayer.h
|——Transform.cpp
|——Transform.h
㈣網路引擎庫
網路引擎庫主要是用來實現Web瀏覽器的引擎,支援Android的Web瀏覽器和一個可嵌入的Web檢視,這是採用第三方開發的瀏覽器引擎Webkit實現的,Webkit的程式碼在/external/webkit/目錄下,其目錄結構如下所示:
external/webkit/
|——Examples //Webkit的例子
|——LayoutTests//佈局測試
|——PerformanceTests//表現測試
|——Source//Webkit原始碼
|——Tools//工具
|——WebKitLibraries//Webkit用到的庫
|——Android.mk//Makefile
|——bison_check.mk
|——CleanSpec.mk
|——MODULE_LICENSE_LGPL//證書
|——NOTICE
|——WEBKIT_MERGE_REVISION//版本資訊
㈤3D圖形庫
Android中的3D圖形渲染是採用OpenGL來實現的,OpenGl是開源的第三方圖形渲染庫,使用該庫可以實現Android中的3D圖形硬體加速或者3D圖形軟體加速功能,是一個非常重要的功能庫。從Android 4.3開始,支援最新,最強大的OpenGL ES3.0.其實現程式碼在/frameworks/native/opengl中,其目錄結構如下所示:
frameworks/native/opengl/
|——include//OpenGL中的標頭檔案
|——libagl//在Mac OS上的庫
|——libs//OpenGL的介面和實現庫
|——specs//OpenGL的文件
|——tests//測試相關
|——tools//工具庫
㈥SQLite
SQLite是Android系統自帶的一個輕量級關係資料庫,其實現原始碼已經在網上開源。SQLite的優點是操作方便,執行速度較快,佔用資源較少等,比較適合在嵌入式裝置上面使用。SQLite是Android系統自帶的實現資料庫功能的核心庫,其程式碼實現分為Java和C兩個部分,Java部分的程式碼位於/frameworks/base/core/java/android/database,目錄結構如下所示:
frameworks/base/core/java/android/database/
|——sqlite//SQLite的框架檔案
|——AbstractCursor.java//遊標的抽象類
|——AbstractWindowedCursor.java
|——BulkCursorDescriptor.java
|——BulkCursorNative.java
|——BulkCursorToCursorAdaptor.java//遊標介面卡
|——CharArrayBuffer.java
|——ContentObservable.java
|——ContentObserver.java
|——CrossProcessCursor.java
|——CrossProcessCursorWrapper.java//CrossProcessCursor的封裝類
|——Cursor.java//遊標實現婁
|——CursorIndexOutOfBoundsException.java//遊標出界異常
|——CursorJoiner.java
|——CursorToBulkCursorAdaptor.java//介面卡
|——CursorWindow.java//遊標視窗
|——CursorWindowAllocationException.java//遊標視窗異常
|——CursorWrapper.java//遊標封裝類
|——DatabaseErrorHandler.java//資料庫錯誤控制代碼
|——DatabaseUtils.java//資料庫工具類
|——DataSetObservable.java
|——DataSetObserver.java
|——DefaultDatabaseErrorHandle.java//預設資料庫錯誤控制代碼
|——IBulkCursor.java
|——IContentObserver.aidl//aidl用於跨程序通訊
|——MatrixCursor.java
|——MergeCursor.java
|——Observable.java
|——package.html
|——SQLException.java//資料庫異常
|——StaleDataException.java
Java層的程式碼主要是實現SQLite的框架和介面的實現,使使用者開發應用程式時能很簡單地操作資料庫,並且捕獲資料庫異常。
C++層的程式碼在/external/sqlite路徑下,其目錄結構如下所示:
external/sqlite/
|——android//Android資料庫的一些工具包
|——dist//Android資料庫底層實現
從上面Java和C部分的程式碼目錄結構可以看出,SQLite在Android中還是有很重要的地位的,並且在SDK中會有開放的介面讓應用程式可以很簡單方便地操作資料庫,對資料進行儲存和刪除。
6.系統執行庫
眾所周知,Android系統折應用層是採用Java開發的,由於Java語言的跨平臺特性,Java程式碼必須執行在虛擬機器中。正是因為這個特性,Android系統也自己實現了一個類似JVM但是更適用於嵌入式平臺的Java虛擬機器,這被稱為dalvik。
dalvik功能等同於JVM,為Android平臺上的Java程式碼提供了執行環境,dalvik本身是由C++語言實現的,在原始碼中的根目錄下有dalvik資料夾,裡面存放的是dalvik虛擬機器的實現程式碼,其目錄結構如下所示:
dalvik/
|——dalvikvm //入口目錄
|——dexdump//dex反彙編
|——dexgen//dex生成相關
|——dexlist//dex列表
|——dexopt//與驗證和優化
|——docs//文件
|——dvz//zygot相關
|——dx//dx工具,將多個Java轉換為dex
|——hit
|——libdex//dex庫的實現程式碼
|——opcode-gen
|——tests//測試相關
|——tools//工具
|——unit-tests //測試相關
|——vm//虛擬機器的實現
|——Android.mk //Makefile
|——CleanSpec.mk
|——MODULE_LICENSE_APACHE2
|——NOTICE
|——README.txt
正是因為的上面這些程式碼實現的Android虛擬機器,所以應用程式生成的二進位制執行檔案能夠快速,穩定執行在Android系統上。
7.硬體抽象層
Android的硬體抽象是各種功能的底層實現,理論上,不同的硬體平臺會有不同的硬體抽象層實現,這一個層次也是與驅動層和硬體層有緊密聯絡的,起著承上啟下的作用,對上要實現應用程式框架層的介面,對下要實現一些硬體的基本功能,以及呼叫驅動層的介面。需要注意的是,這一層也是廣大OEM廠商改動最大的一層,因為這一層的程式碼跟終端採用什麼樣硬體的硬體平臺的很大的關係。原始碼中存放的是硬體抽象層框架的實現程式碼和一些平臺無關的介面的實現。硬體抽象層程式碼在原始碼根目錄下的hardware資料夾中,其目錄結構如下所示:
hardware/
|——libhardware//新機制硬體庫
|——libhardware_legacy//舊機制硬體庫
|——ril//ril模組相關的底層實現
從上面的目錄結構我們可以看出,硬體抽象層中主要是實現了一些底層的硬體庫,用來實現應用層框架中的功能,至於其體硬體庫中的哪些內容,我們可以繼續分其目錄結構,例如libhardware目錄下的結構為:
hardware/libhardware/
|——include//入口目錄
|——modules//dex反彙編
|——|——audio //音訊相關底層庫
|——|——audio_remote_submix//音訊混合相關
|——|——gralloc //幀緩衝
|——|——hwcomposer //音訊相關
|——|——local_time //本地時間
|——|——nfc//nfc功能
|——|——nfc-nci //nfc介面
|——|——power //電源
|——|——usbaudio //USB音訊裝置
|——|——Android.mk //Makefile
|——|——README.android
|——tests//dex生成相關
|——dexlist//dex列表
|——dexopt//驗證和優化
|——docs//文件
從上面的目錄結構我們可以分析出,libhardware目錄主要是Android系統的某些功能的底層實現,包括audio,nfc,power。
libhardware_legacy目錄與libhardware大同小異,只是針對舊的實現方式做的一套硬體庫,其目錄下還有uevent,wifi以及虛擬機器的底層實現。這兩個目錄下的程式碼一般會由裝置廠家根據自身的硬體平臺來實現符合Android機制的硬體庫。
ril目錄下存放的是無線硬體裝置與電話的實現,其目錄結構如下所示:
hardware/ril/
|——include//標頭檔案
|——libril//libril庫
|——mock-ril
|——reference-ril //reference ril庫
|——rild//ril守護程序
|——CleanSpec.mk