Android核心剖析

Android核心剖析

《Android核心剖析》是電子工業出版社2011年9月1日出版的圖書,作者是柯元旦。本書詳細分析了Android核心的內部機制,包括視窗管理系統、Activity管理系統、輸入法框架、編譯系統等,為Android核心定製及高級應用程式開發提供技術參考。

基本介紹

  • 書名:Android核心剖析
  • 作者:柯元旦
  • ISBN: 9787121143984 
  • 頁數:616頁
  • 出版社: 電子工業出版社
  • 出版時間:2011年9月1日
  • 開本:16
內容簡介,作品目錄,

內容簡介

本書適合於所有Android相關的工程師及產品經理,還可作為相關培訓機構的教材。
1. 什麼是Android核心
Android作業系統是基於Linux實現的,然而Android的核心價值卻不是Linux,所以說,Android的核心不是指Linux,本書不是一本介紹Linux的書。這就好比蘋果的作業系統iOS是基於Unix實現的,然而iOS的核心價值卻不是Unix。
那么,Android的核心是什麼,它的核心價值都包含什麼?
大家聽過和Android核心最多的詞語應該是“Android Framework”以及“Dalvik虛擬機”,那么,這兩個核心部分從內部運行機制的角度來看,到底扮演著什麼角色,彼此之間如何協同工作呢?了解清楚了這些,也就了解了所謂Android的核心價值,即Android核心。
從進程的角度來看,Android的運行環境如下圖所示:
Linux核心啟動後,此時系統的狀態和普通的Linux系統基本相同,通過配置Linux中的init.rc檔案,可以指定核心啟動後都要執行什麼程式,而這之後所啟動的程式才是Android系統和普通Linux套用系統的區別。
Android核心剖析
init.rc中所啟動的一個重要進程被稱作zygote進程,如上圖中紅色框線所示,zygote這個英文單詞的意思是“受精卵”,本書將其稱為“種子進程”,從進程的角度來看,種子進程僅僅是一個Linux進程而已,它和一個只包含main()函式的C程式所產生的進程是同一個級別,如上圖中雙實線框線所示。
種子進程裡面所運行的程式基本上就是Android核心的精華所在,其內部主要完成了兩件事情。第一件事情是裝載了一段程式代碼,這些代碼都是用C語言寫的,這段代碼的作用只是為了能夠執行Java編譯器編譯出的位元組碼,這段代碼就是傳說中的Java虛擬機,在Android中稱為Dalvik虛擬機。
第二件事情必須基於第一件事情之後,即當Dalvik虛擬機代碼初始化完成後,從一個名為ZygoteInit.java類中的main()函式中開始執行。這裡大家就奇怪了,Dalvik虛擬機如何知道ZygoteInit這個Java類在哪個Jar包裡面?實際上,這個Jar包的目錄位置信息正是在init.rc中進行配置的,只不過沒有直接指定,而是使用一個標誌符,當這個標誌符是“zygote”時,Dalvik虛擬機就會從“硬編碼”的字元串中得到ZygoteInit類所在的Jar包,而這個Jar包正是framework.jar。
接下來的事情即是簡單的,又是複雜的。所謂簡單是指,ZygoteInit類中main()函式所做的事情和Linux本身就沒多大關係了,理論上完全可以在該main()函式中實現任意簡單的功能;所謂複雜是指,該main()函式中才剛剛開始啟動Android的核心功能。
在ZygoteInit類中的main()函式中,首先載入一些類檔案,這些類將作為以後所有其它Apk程式共享的類,接著,會創建一個Socket服務端,該服務端將用於通過Socket啟動新進程。
該進程之所以被稱為“種子”進程的原因就是,當其內部的Socket服務端收到啟動新的Apk進程的請求時,會使用Linux的一個系統調用folk()函式從自身複製出一個新的進程,新進程和Zygote進程將共享已經裝載的類,這些類都是在framework.jar中定義的。
以上從進程的角度分析了Android核心的概念,下面從圖形用戶界面的角度再來看看Android核心的含義。大家都知道,Linux核心所提供的功能主要包括:
l 驅動模型
這些功能都是和用戶界面沒有關係的,核心一般僅僅會通過USB接口或者RS232串口輸出一些狀態信息,而對於視窗作業系統而言,這還遠遠不夠,最重要的就是作業系統應該提供一套用戶界面子系統,該子系統包含如何創建、刪除視窗,以及用戶如何和視窗進行互動,同時還應該提供一套界面程式庫,以便第三方開發商能夠基於該界面庫快速的開發一些視窗應用程式。而這就是Android最核心的內容,完成這些功能的代碼大部分都在那個framework.jar檔案中,Dalvik虛擬機只不過是執行這些功能代碼的一個環境而已。
因此,如果考慮圖形用戶界面,則一個Android應用程式的內部關係如下圖所示:
首先,內部模組可分為三個大部分,分別是:
Android核心剖析
第一部分,Linux驅動端。該模組重新把標準Linux驅動抽象為Android所定義的硬體接口,從而保持了Android核心代碼的獨立性,即當Linux驅動有變動時,只需要修改該適配層,而不需要再修改Android核心的代碼。該驅動端也被稱作硬體抽象層(Harware Abstarction Layout)。
第二部分,Framework服務端,該服務端主要進行輸入訊息的處理,並將訊息傳遞給視窗管理服務執行緒(WmS),WmS內部會根據當前所有套用視窗的層次關係,決定應該把這個訊息派發給哪個視窗。除了WmS外,還包含一個核心執行緒組件,即Activity管理執行緒(AmS),Activity是Android中定義的一個程式片段,這個片段可理解為“可以被動態載入的程式”,即,當套用執行緒啟動後,可以根據用戶的操作,有選擇的載入不同的Activity。
第三部分,Apk應用程式客戶端。每一個Apk應用程式的客戶端都是從ActivityThread類中的main()函式開始執行,這和一個普通的Java程式完全相同,當ActivityThread啟動後,會向AmS報告說“自己已經啟動了,請告訴我要執行哪一個Activity片段”,AmS會通過進程間通信(Inter Process Communication)的方式把要載入的Activity信息告訴給ActivityThread,從而ActivityThread執行指定的Activity,而在Activity內部會調用Framework中提供的各種添加視窗的函式進行視窗的添加和刪除。
Android核心剖析就是圍繞以上過程進行徹底的剖析。
2. Android核心剖析的思路
了解了以上Android核心的定義後,自然會想到以下問題,同時,問題會再被細化更多問題,比如?
l 什麼是一個Apk程式,該Apk程式是怎么被編譯出來的,ActivityThread中是如何載入該Apk程式的?
l 當用戶在螢幕上點擊一個套用圖示後,訊息如何被傳遞到AmS中,AmS又是如何知道該圖示對應的信息,以及如何啟動對應的Apk進程?
l 套用進程中Activity內部如何添加一個套用視窗,該視窗在WmS內部如何被保存,當一個觸摸訊息發生後,WmS如何知道這個訊息對應哪個視窗?
l 在應用程式內部,一個ViewGroup對象以及一個View對象是如何被繪製到螢幕上,onDraw()是如何被調用的?
l OptionMenu、ContextMenu和Dialog添加視窗的方式有什麼不同?
l 什麼是一個Context對象,它與Activity之間是什麼關係?
l Activity、“視窗”、Window、View,這些概念或者類在代碼上是什麼關係?
l 資源檔案是如何被載入的,系統資源和套用資源是什麼關係?如何改變載入系統資源的路徑從而達到替換系統資源的目的?
l 輸入法視窗和普通套用視窗之間的關係如何?為什麼輸入法管理器沒有提供查詢輸入法視窗大小的接口,以及為什麼不提供查詢是否輸入法視窗顯示在界面上的接口?
l 如何編寫一個新的輸入法?
l AndroidManifest.xml中申請的許可權是如何保存在系統中的,這些許可權在運行時是如何被檢查的?
l Apk是如何被安裝和卸載的?
l framework.jar包是如何被編譯出來的,如何添加一些私有的framework類,並不把這些類暴露給SDK?
l 如何編譯不同的子工程,比如Linux動態庫、靜態庫、Jar包等?如何給Java工程中增加JNI代碼並編譯?
l 有沒有可能把framework改造為沒有界面的系統,僅運行一些後台服務?
l 如何給Android增加一個外部顯示器的功能?
這裡僅僅列出一些常見的問題,也僅僅是一些問題入口,在具體分析一個問題是又會引出新的問題,本書作者分析的思路也是如此,但在目錄安排上則是將分析後的結果按照內在的關係重新組織在一起。
3. 本書目標
從工程的設計需要來講,本書適合的目標群體如下圖綠色部分所示,紅色部分為不適合的讀者對象,黃色表示本書未來會增加的內容。
4. 讀者對象
Android核心剖析
由於Android核心剖析的本質不是剖析Linux,因此,本書的讀者不需要有任何Linux基礎,而只要熟練使用C語言和Java語言即可。
另外,從作者對iOS套用層的分析來看,其圖形用戶界面(GUI)的設計架構思想和Android有非常相似的地方,而iOS不是開源的,因此,iOS的開發者也可以參考本書來理解一些GUI內部機制,從而有助於上層的套用開發。

作品目錄

第1部分 基礎篇
第1章 Linux基礎 2
1.1 Linux檔案系統概述 2
1.2 Linux啟動過程 4
1.3 常用Linux 命令 6
1.4 Shell腳本備忘 9
1.5 Make腳本備忘 15
第2章 Java基礎 26
2.1 類裝載器DexClassLoader 26
2.2 JNI調用機制 32
2.3 異步訊息處理執行緒 37
第3章 Android源碼下載及開發環境配置 44
3.1 Mac系統的配置 44
3.2 在Linux中配置USB連線 46
3.3 在Eclipse中調試Framework 46
第4章 使用git 51
4.1 安裝git 52
4.2 git倉庫管理 52
4.3 git merge用法 57
4.4 git rebase用法 58
4.5 git cherry-pick用法 61
4.6 git reset用法 62
4.7 恢復到無引用提交 63
4.8 git remote用法 65
4.9 git 配置 67
4.10 同時使用git和svn 71
4.11 其他git常用命令示例 72
第2部分 核心篇
第5章 Binder 78
5.1 Binder框架 78
5.2 設計Servier端 80
5.3 Binder客戶端設計 81
5.4 使用Service類 82
5.5 系統服務中的Binder對象 88
第6章 Framework概述 92
6.1 Framework框架 92
6.2 APK程式的運行過程 94
6.3 客戶端中的執行緒 94
6.4 幾個常見問題 95
第7章 理解Context 98
7.1 Context是什麼 98
7.2 一個應用程式中包含多少個Context對象 99
7.3 Context相關類的繼承關係 99
7.4 創建Context 100
第8章 創建視窗的過程 106
8.1 視窗的類型 106
8.2 token變數的含義 108
8.3 創建套用視窗 111
8.4 創建子視窗 121
8.5 系統視窗Toast的創建 136
8.6 創建視窗示例 139
第9章 Framework的啟動過程 142
9.1 Framework運行環境綜述 142
9.2 Dalvik虛擬機相關的可執行程式 143
9.3 zygote的啟動 147
9.4 SystemServer進程的啟動 155
第10章 AmS內部原理 160
10.1 Activity調度機制 160
10.3 對AmS中數據對象的理解 211
10.4 ActivityGroup的內部機制 214
第11章 從輸入設備中獲取訊息 221
11.1 Android訊息獲取過程概述 221
11.2 與訊息處理相關的源碼檔案分布 223
11.3 創建InputDispatcher執行緒 226
11.4 把視窗信息傳遞給InputDispatcher執行緒 227
11.5 創建InputChannel 229
11.6 在WmS中註冊InputChannel 232
11.7 在客戶進程中註冊InputChannel 233
11.8 WmS中處理訊息的時機 234
11.9 客戶視窗獲取訊息的時機 235
第12章 螢幕繪圖基礎 237
12.1 繪製螢幕的軟體架構 237
12.2 Java客戶端繪製調用過程 239
12.3 C客戶端繪製過程 241
12.4 Java客戶端繪製相關類的關係 244
第13章 View工作原理 247
13.1 導論 247
13.2 用戶訊息類型 249
13.3 按鍵訊息派發過程 252
13.4 按鍵訊息在WmS中的派發過程 263
13.5 觸摸訊息派發過程 266
13.6 導致View樹重新遍歷的時機 274
13.7 遍歷View樹performTraversals()的執行過程 293
13.8 計算視圖大小(measure)的過程 296
13.9 布局(layout)過程 308
13.10 繪製(draw)過程 313
13.11 動畫的繪製 331
第14章 WmS工作原理 340
14.1 概述 340
14.2 WmS主要內部類 348
14.3 視窗的創建和刪除 355
14.4 計算視窗的大小 371
14.5 切換視窗 379
14.6 perforLayoutAndPlaceSurfacesLockedInner()的執行過程 398
14.7 視窗動畫 406
14.8 螢幕旋轉及Configuration的變化過程 409
第3部分 系統篇
第15章 資源訪問機制 414
15.1 定義資源 414
15.2 存儲資源 415
15.3 styleable、style、attr、theme的意義 417
15.4 AttributeSet與TypedArray類 420
15.5 獲取Resources的過程 425
15.6 Framework資源 431
第16章 程式包管理(Package Manager Service) 439
16.1 包管理概述 439
16.2 packages.xml檔案格式 442
16.3 包管理服務的啟動過程 446
16.4 應用程式的安裝和卸載 455
16.5 intent匹配框架 463
第17章 輸入法框架 467
17.1 輸入法框架組成概述 468
17.2 輸入法中各Binder對象的創建過程 469
17.3 輸入法主要操作過程 477
17.4 輸入法視窗內部的顯示過程 490
17.5 向編輯框傳遞字元 503
17.6 輸入法相關源碼清單 504
第4部分 編譯篇
第18章 Android編譯系統 508
18.1 Android源碼檔案結構 509
18.2 從調用make命令開始說起 509
18.3 編譯所需腳本檔案之間的協同關係 512
18.4 如何增加一個product 523
18.5 如何增加一個項目 528
18.6 APK編譯過程 533
18.7 Framework的編譯 544
18.8 編譯android.jar 547
18.9 編譯adt外掛程式 553
18.10 總結 554
第19章 編譯自己的Rom 555
19.1 嵌入式系統的記憶體地址空間 555
19.2 各種映像(Image)檔案的作用 559
19.3 編譯Nexus S(NS)的Image檔案 562
19.4 使用fastboot寫入Image檔案 566
19.5 最後驗證 567
第5部分 硬體驅動篇
第20章 基於TI OMAP處理器的 Techshine 開發板介紹 573
20.1 Techv-35XX開發板概述 574
20.2 交叉編譯環境配置 575
20.3 x-loader編譯 578
20.4 u-boot編譯 578
20.5 Techv-35XX Linux驅動和核心配置及編譯 579
20.6 Techv-35XX Android驅動編寫 584
20.7 Techv-35XX Android開發環境建立 589
20.8 編譯Android Donut 590
20.9 Android根檔案系統的製作 591
20.10 相關Image檔案的燒寫 591
20.11 Android 根檔案系統安裝 593

相關詞條

熱門詞條

聯絡我們