當前位置:首頁 » 安卓系統 » 分析android源碼

分析android源碼

發布時間: 2022-09-08 14:20:17

1. 如何查看Android源碼

當我們在eclipse中開發android程序的時候,往往需要看源代碼(可能是出於好奇,可能是讀源碼習慣),那麼如何查看Android源代碼呢?

比如下面這種情況

假設我們想參看Activity類的源代碼,按著Ctrl鍵,左擊它,現實的結果卻看不到代碼的,提示的信息便是「找不到Activity.class文件」。

此時點擊下面的按鈕,「Change Attached Source…」,選擇android源代碼所在位置,便彈出圖三的對話框。

第一種是選擇工作目錄,即已經存在的android應用程序源代碼。

第二種分兩種方式

(1)選擇External File…按鈕,添加Jar格式文件或者zip格式文件路徑;

(2)選擇External Floder…按鈕,添加文件夾所在路徑。

下面問題就來了,源代碼在哪裡?不能憑空產生阿。

可以通過Android SDK Manager進行源代碼下載;(推薦該種方法),如圖四

勾選Source for Android SDK,進行下載即可。

此外也可通過其他途徑下載,網上有很多共享的資源。

這里選擇第二種方式的(2)方法,選擇源碼所在目錄(即圖四下載源代碼目錄所在路徑),如圖五

點擊「OK」按鈕,此時,Activity文件便能夠查看源代碼了,如圖六。

這樣就大功告成了!!!

2. 基於android的內核與系統架構源碼分析怎麼樣

如今,大家面對市場中種類繁多的手機必然挑的眼花繚亂。不過,在智能手機占據主要地位的今天,挑選手機的主要因素就是挑選一款性能高的手機操作系統,Android就是其中的一個必然選擇。Android系統架構和其操作系統一樣,採用了分層的架構。Android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。 Android系統架構之應用程序 Android會同一系列核心應用程序包一起發布,該應用程序包包括email客戶端,SMS短消息程序,日歷,地圖,瀏覽器,聯系人管理程序等。所有的應用程序都是使用java語言編寫的。 Android系統架構之應用程序框架 開發人員也可以完全訪問核心應用程序所使用的API框架。該應用程序的架構設計簡化了組件的重用;任何一個應用程序都可以發布它的功能塊並且任何其它的應用程序都可以使用其所發布的功能塊(不過得遵循框架的安全性限制)。同樣,該應用程序重用機制也使用戶可以方便的替換程序組件。 隱藏在每個應用後面的是一系列的服務和系統, 其中包括; * 豐富而又可擴展的視圖(Views),可以用來構建應用程序, 它包括列表(lists),網格(grids),文本框(text boxes),按鈕(buttons), 甚至可嵌入的web瀏覽器。 * 內容提供器(Content Providers)使得應用程序可以訪問另一個應用程序的數據(如聯系人資料庫), 或者共享它們自己的數據 * 資源管理器(Resource Manager)提供 非代碼資源的訪問,如本地字元串,圖形,和布局文件( layout files )。 * 通知管理器 (Notification Manager) 使得應用程序可以在狀態欄中顯示自定義的提示信息。 * 活動管理器( Activity Manager) 用來管理應用程序生命周期並提供常用的導航回退功能。 有關更多的細節和怎樣從頭寫一個應用程序,請參考 如何編寫一個 Android 應用程序. Android系統架構之系統運行庫 1)程序庫 Android 包含一些C/C++庫,這些庫能被Android系統中不同的組件使用。它們通過 Android 應用程序框架為開發者提供服務。以下是一些核心庫: * 系統 C 庫 - 一個從 BSD 繼承來的標准 C 系統函數庫( libc ), 它是專門為基於 embedded linux 的設備定製的。 * 媒體庫 - 基於 PacketVideo OpenCORE;該庫支持多種常用的音頻、視頻格式回放和錄制,同時支持靜態圖像文件。編碼格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 。 * Surface Manager - 對顯示子系統的管理,並且為多個應用程序提 供了2D和3D圖層的無縫融合。 * LibWebCore - 一個最新的web瀏覽器引擎用,支持Android瀏覽器和一個可嵌入的web視圖。 * SGL - 底層的2D圖形引擎 * 3D libraries - 基於OpenGL ES 1.0 APIs實現;該庫可以使用硬體 3D加速(如果可用)或者使用高度優化的3D軟加速。 * FreeType -點陣圖(bitmap)和矢量(vector)字體顯示。 * SQLite - 一個對於所有應用程序可用,功能強勁的輕型關系型資料庫引擎。 2)Android 運行庫 Android 包括了一個核心庫,該核心庫提供了JAVA編程語言核心庫的大多數功能。 每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。Dalvik被設計成一個設備可以同時高效地運行多個虛擬系統。 Dalvik虛擬機執行(.dex)的Dalvik可執行文件,該格式文件針對小內存使用做了優化。同時虛擬機是基於寄存器的,所有的類都經由JAVA編譯器編譯,然後通過SDK中 的 “dx” 工具轉化成.dex格式由虛擬機執行。 Dalvik虛擬機依賴於linux內核的一些功能,比如線程機制和底層內存管理機制。 Android系統架構之Linux 內核 Android 的核心系統服務依賴於 Linux 2.6 內核,如安全性,內存管理,進程管理, 網路協議棧和驅動模型。 Linux 內核也同時作為硬體和軟體棧之間的抽象層。

3. 怎樣評價羅升陽的android系統源代碼分析

我幹了3年Android sdk開發,覺得到了瓶勁沒法更進一步,於是花了一年多點時間,大概摸到點門徑。根據前輩的經驗,Android底層完全入門需要兩年。 先說下我的入門過程: 第零步,下載源碼,我下的4.2的,框架層源碼10G,內核2G多,ctags給框架層建的標簽文件都有600M,當時讓我有點震撼,用的vim+ctags+cscope來閱讀,還算不錯,架構挺清晰的。 第一步,我找到了一本好書《Android的設計與實現 第一卷》它講了Android框架層的啟動,初始化,服務框架初始化,Binder,消息循環,PackageManagerService,ActivityManagerService。據作者說後面會出講UI子系統的第二卷,拭目以待。其實這本書看了幾十頁我就發現需要第二步的知識,否則看不下去,於是跳去第二步。 第二步,學習Linux系統編程,在看《Android的設計與實現》的時候我發現,框架層的Native部分,全是Linux編程。為了掌握這部分知識,我花了4個月學習了《Linux系統編程手冊》(TLPI)這本1000多頁的書,我以前是搞WIndows文件系統這塊的,所以C語言還比較熟,TLPI的習題很有意思,量也比較大,堅持下來還是收獲很多。 第三步,花了4個月學習了一些Linux內核的知識,看了LKD,PLKA看了一半多。越學越沒底,覺得不懂得越來越多,不過這個也正常,只有靠慢慢磨,估計以後要不斷的磨這塊。 第四步,回頭看Android源碼,這次一口氣看完了《Android的設計與實現 第一卷》,終於對框架層有了譜。同時真的數次把我看暈,前面看Linux內核源碼都沒這么暈,不斷在Java層和Native層之間跳有點磨腦漿。其中我又覺得Java的基礎沒有打太牢,回去補了一個月的《Core Java》第八版。但是這書沒有涉及UI子系統,於是又看了《Android內核剖析》 第五步,《Android內核剖析》(這本書實際上是講框架層的,作者也是個搞嵌入式的,所以他在寫框架層的時候文筆不太好,很羅嗦,不過還是有很多看點,到他後來寫做ROM,玩開發板時估計是說到了他的本行,一下子遛起來了看得出還是挺有水平的,這本書知識有點舊畢竟講的是2.3很多代碼已經過時,但是作者很多點子很有參考價值)這本書講UI子系統和按鍵/觸摸消息處理系統還是很有分量的,尤其13章View繪制那裡,結合源碼研究很有收獲。而後面他講編譯框架和ROM相關的東西都是挺寶貴的資料。 第六步,為了再補一下其他諸如電源管理模塊等子系統的知識看了,《深入理解android》系列,個人認為這個系列看起來有點不太舒服,不過作為補充印證還是比較有價值。 第七步,《Android系統源代碼情景分析》,羅升陽的源碼分析大作,比《Android的設計與實現》分析得更細致,但缺點是涉及到模塊比較少,選用的源碼也比《Android的設計與實現》更舊一點。看完書後需要去研究作者的博客,東西挺多的,一定讓你滿意。 第八步,買塊開發板自己玩。這步我還沒走到,原因是我覺得我還差點准備知識。可能要再幾個月,到時准備入塊6410或者樹莓派。 最後,由於我11年以前都是搞Windows這塊的,所以對Linux知識不是很了解,不得已看了這么些書,如果是一直做Linux的人,很多步驟估計可以省掉了。直接上源碼才是正道。 我本身做著移動GIS開發的工作,學框架層全是因為興趣,但招聘平台Android框架層開發人員還是蠻有競爭力的有不少定製ROM,智能電視的工作都處於人才難求狀態,畢竟有一定的門檻,現在各種ios培訓,讓奔著錢干開發的人紛紛湧入,而ios只能幹sdk開發的缺點就暴露出來了,一堆新手老手,菜鳥大牛全擠在SDK開發這塊,我覺得不太妙。 反觀Android這邊,雖然入門菜鳥沒有搞ios來錢,但是可持續性很好,從sdk-》框架》驅動》內核這樣幹下去。干著干著發現自己漸漸變成了Linux開發者/嵌入式開發者的人也不少,新人,老手,菜鳥大牛各居其位,層次性很好。 轉載

4. 分析Android系統源碼有沒有大量使用C++

由於工作需要大量修改framework代碼, 在AOSP(Android Open Source Project)源碼上花費了不少功夫, Application端和Services端都看和改了不少,如果只是想看看一些常用類的實現, 在Android包管理器里把源碼下載下來, 隨便一個IDE配好Source Code

5. 怎麼分析一個android應用程序的源碼

一般工程的AndroidManifest.xml里包含下面代碼的是主界面

<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>

<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>

找到主界面後就根據主界面的函數找其他界面的入口,一點一點的分析就好了

6. 做jni開發android系統源碼怎麼分析

Android中JNI是編譯so庫的源代碼,編譯成功後會生成SO庫,android中最終是使用SO庫的。
1.android的NDK開發需要在linux下進行: 因為需要把C/C++編寫的代碼生成能在arm上運行的.so文件,這就需要用到交叉編譯環境,而交叉編譯需要在linux系統下才能完成。
2.安裝android-ndk開發包,這個開發包可以在google android 官網下載: 通過這個開發包的工具才能將android jni 的C/C++的代碼編譯成庫
3.android應用程序開發環境: 包括eclipse、java、 android sdk、 adt等。

7. 求《Android源碼分析實錄李忠良》全文免費下載百度網盤資源,謝謝~

《Android源碼分析實錄李忠良》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1p1F5-Rb1wcS4XRPz_SJjrQ

?pwd=rt83 提取碼: rt83
簡介:Android源碼分析實錄李忠良pdf全書共分為15章,分別講述了分析JNI層、Android內存系統分析、Andmid虛擬機系統詳解、IPC通信機制詳解等,幫助讀者能一步一步了解Android系統核心源碼核心知識。

8. Android socket源碼解析(三)socket的connect源碼解析

上一篇文章著重的聊了socket服務端的bind,listen,accpet的邏輯。本文來著重聊聊connect都做了什麼?

如果遇到什麼問題,可以來本文 https://www.jianshu.com/p/da6089fdcfe1 下討論

當服務端一切都准備好了。客戶端就會嘗試的通過 connect 系統調用,嘗試的和服務端建立遠程連接。

首先校驗當前socket中是否有正確的目標地址。然後獲取IP地址和埠調用 connectToAddress 。

在這個方法中,能看到有一個 NetHooks 跟蹤socket的調用,也能看到 BlockGuard 跟蹤了socket的connect調用。因此可以hook這兩個地方跟蹤socket,不過很少用就是了。

核心方法是 socketConnect 方法,這個方法就是調用 IoBridge.connect 方法。同理也會調用到jni中。

能看到也是調用了 connect 系統調用。

文件:/ net / ipv4 / af_inet.c

在這個方法中做的事情如下:

注意 sk_prot 所指向的方法是, tcp_prot 中 connect 所指向的方法,也就是指 tcp_v4_connect .

文件:/ net / ipv4 / tcp_ipv4.c

本質上核心任務有三件:

想要能夠理解下文內容,先要明白什麼是路由表。

路由表分為兩大類:

每個路由器都有一個路由表(RIB)和轉發表 (fib表),路由表用於決策路由,轉發表決策轉發分組。下文會接觸到這兩種表。

這兩個表有什麼區別呢?

網上雖然給了如下的定義:

但實際上在Linux 3.8.1中並沒有明確的區分。整個路由相關的邏輯都是使用了fib轉發表承擔的。

先來看看幾個和FIB轉發表相關的核心結構體:

熟悉Linux命令朋友一定就能認出這裡面大部分的欄位都可以通過route命令查找到。

命令執行結果如下:

在這route命令結果的欄位實際上都對應上了結構體中的欄位含義:

知道路由表的的內容後。再來FIB轉發表的內容。實際上從下面的源碼其實可以得知,路由表的獲取,實際上是先從fib轉發表的路由字典樹獲取到後在同感加工獲得路由表對象。

轉發表的內容就更加簡單

還記得在之前總結的ip地址的結構嗎?

需要進行一次tcp的通信,意味著需要把ip報文准備好。因此需要決定源ip地址和目標IP地址。目標ip地址在之前通過netd查詢到了,此時需要得到本地發送的源ip地址。

然而在實際情況下,往往是面對如下這么情況:公網一個對外的ip地址,而內網會被映射成多個不同內網的ip地址。而這個過程就是通過DDNS動態的在內存中進行更新。

因此 ip_route_connect 實際上就是選擇一個緩存好的,通過DDNS設置好的內網ip地址並找到作為結果返回,將會在之後發送包的時候填入這些存在結果信息。而查詢內網ip地址的過程,可以成為RTNetLink。

在Linux中有一個常用的命令 ifconfig 也可以實現類似增加一個內網ip地址的功能:

比如說為網卡eth0增加一個IPV6的地址。而這個過程實際上就是調用了devinet內核模塊設定好的添加新ip地址方式,並在回調中把該ip地址刷新到內存中。

注意 devinet 和 RTNetLink 嚴格來說不是一個存在同一個模塊。雖然都是使用 rtnl_register 注冊方法到rtnl模塊中:

文件:/ net / ipv4 / devinet.c

文件:/ net / ipv4 / route.c

實際上整個route模塊,是跟著ipv4 內核模塊一起初始化好的。能看到其中就根據不同的rtnl操作符號注冊了對應不同的方法。

整個DDNS的工作流程大體如下:

當然,在tcp三次握手執行之前,需要得到當前的源地址,那麼就需要通過rtnl進行查詢內存中分配的ip。

文件:/ include / net / route.h

這個方法核心就是 __ip_route_output_key .當目的地址或者源地址有其一為空,則會調用 __ip_route_output_key 填充ip地址。目的地址為空說明可能是在回環鏈路中通信,如果源地址為空,那個說明可能往目的地址通信需要填充本地被DDNS分配好的內網地址。

在這個方法中核心還是調用了 flowi4_init_output 進行flowi4結構體的初始化。

文件:/ include / net / flow.h

能看到這個過程把數據中的源地址,目的地址,源地址埠和目的地址埠,協議類型等數據給記錄下來,之後內網ip地址的查詢與更新就會頻繁的和這個結構體進行交互。

能看到實際上 flowi4 是一個用於承載數據的臨時結構體,包含了本次路由操作需要的數據。

執行的事務如下:

想要弄清楚ip路由表的核心邏輯,必須明白路由表的幾個核心的數據結構。當然網上搜索到的和本文很可能大為不同。本文是基於LInux 內核3.1.8.之後的設計幾乎都沿用這一套。

而內核將路由表進行大規模的重新設計,很大一部分的原因是網路環境日益龐大且復雜。需要全新的方式進行優化管理系統中的路由表。

下面是fib_table 路由表所涉及的數據結構:

依次從最外層的結構體介紹:

能看到路由表的存儲實際上通過字典樹的數據結構壓縮實現的。但是和常見的字典樹有點區別,這種特殊的字典樹稱為LC-trie 快速路由查找演算法

這一篇文章對於快速路由查找演算法的理解寫的很不錯: https://blog.csdn.net/dog250/article/details/6596046

首先理解字典樹:字典樹簡單的來說,就是把一串數據化為二進制格式,根據左0,右1的方式構成的。

如圖下所示:

這個過程用圖來展示,就是沿著字典樹路徑不斷向下讀,比如依次讀取abd節點就能得到00這個數字。依次讀取abeh就能得到010這個數字。

說到底這種方式只是存儲數據的一種方式。而使用數的好處就能很輕易的找到公共前綴,在字典樹中找到公共最大子樹,也就找到了公共前綴。

而LC-trie 則是在這之上做了壓縮優化處理,想要理解這個演算法,必須要明白在 tnode 中存在兩個十分核心的數據:

這負責什麼事情呢?下面就簡單說說整個lc-trie的演算法就能明白了。

當然先來看看方法 __ip_dev_find 是如何查找

文件:/ net / ipv4 / fib_trie.c

整個方法就是通過 tkey_extract_bits 生成tnode中對應的葉子節點所在index,從而通過 tnode_get_child_rcu 拿到tnode節點中index所對應的數組中獲取葉下一級別的tnode或者葉子結點。

其中查找index最為核心方法如上,這個過程,先通過key左移動pos個位,再向右邊移動(32 - bits)演算法找到對應index。

在這里能對路由壓縮演算法有一定的理解即可,本文重點不在這里。當從路由樹中找到了結果就返回 fib_result 結構體。

查詢的結果最為核心的就是 fib_table 路由表,存儲了真正的路由轉發信息

文件:/ net / ipv4 / route.c

這個方法做的事情很簡單,本質上就是想要找到這個路由的下一跳是哪裡?

在這裡面有一個核心的結構體名為 fib_nh_exception 。這個是指fib表中去往目的地址情況下最理想的下一跳的地址。

而這個結構體在上一個方法通過 find_exception 獲得.遍歷從 fib_result 獲取到 fib_nh 結構體中的 nh_exceptions 鏈表。從這鏈表中找到一模一樣的目的地址並返回得到的。

文件:/ net / ipv4 / tcp_output.c

9. [Android源碼分析] - 非同步通信Handler機制

一、問題:在Android啟動後會在新進程里創建一個主線程,也叫UI線程( 非線程安全 )這個線程主要負責監聽屏幕點擊事件與界面繪制。當Application需要進行耗時操作如網路請求等,如直接在主線程進行容易發生ANR錯誤。所以會創建子線程來執行耗時任務,當子線程執行完畢需要通知UI線程並修改界面時,不可以直接在子線程修改UI,怎麼辦?

解決方法:Message Queue機制可以實現子線程與UI線程的通信。

該機制包括Handler、Message Queue、Looper。Handler可以把消息/ Runnable對象 發給Looper,由它把消息放入所屬線程的消息隊列中,然後Looper又會自動把消息隊列里的消息/Runnable對象 廣播 到所屬線程里的Handler,由Handler處理接收到的消息或Runnable對象。

1、Handler

每次創建Handler對象時,它會自動綁定到創建它的線程上。如果是主線程則默認包含一個Message Queue,否則需要自己創建一個消息隊列來存儲。

Handler是多個線程通信的信使。比如在線程A中創建AHandler,給它綁定一個ALooper,同時創建屬於A的消息隊列AMessageQueue。然後在線程B中使用AHandler發送消息給ALooper,ALooper會把消息存入到AMessageQueue,然後再把AMessageQueue廣播給A線程里的AHandler,它接收到消息會進行處理。從而實現通信。

2、Message Queue

在主線程里默認包含了一個消息隊列不需要手動創建。在子線程里,使用Looper.prepare()方法後,會先檢查子線程是否已有一個looper對象,如果有則無法創建,因為每個線程只能擁有一個消息隊列。沒有的話就為子線程創建一個消息隊列。

Handler類包含Looper指針和MessageQueue指針,而Looper里包含實際MessageQueue與當前線程指針。

下面分別就UI線程和worker線程講解handler創建過程:

首先,創建handler時,會自動檢查當前線程是否包含looper對象,如果包含,則將handler內的消息隊列指向looper內部的消息隊列,否則,拋出異常請求執行looper.prepare()方法。

 - 在 UI線程 中,系統自動創建了Looper 對象,所以,直接new一個handler即可使用該機制;

- 在 worker線程 中,如果直接創建handler會拋出運行時異常-即通過查『線程-value』映射表發現當前線程無looper對象。所以需要先調用Looper.prepare()方法。在prepare方法里,利用ThreadLocal<Looper>對象為當前線程創建一個Looper(利用了一個Values類,即一個Map映射表,專為thread存儲value,此處為當前thread存儲一個looper對象)。然後繼續創建handler, 讓handler內部的消息隊列指向該looper的消息隊列(這個很重要,讓handler指向looper里的消息隊列,即二者共享同一個消息隊列,然後handler向這個消息隊列發送消息,looper從這個消息隊列獲取消息) 。然後looper循環消息隊列即可。當獲取到message消息,會找出message對象里的target,即原始發送handler,從而回調handler的handleMessage() 方法進行處理。

 - handler與looper共享消息隊列 ,所以handler發送消息只要入列,looper直接取消息即可。

 - 線程與looper映射表 :一個線程最多可以映射一個looper對象。通過查表可知當前線程是否包含looper,如果已經包含則不再創建新looper。

5、基於這樣的機制是怎樣實現線程隔離的,即在線程中通信呢。 

核心在於 每一個線程擁有自己的handler、message queue、looper體系 。而 每個線程的Handler是公開 的。B線程可以調用A線程的handler發送消息到A的共享消息隊列去,然後A的looper會自動從共享消息隊列取出消息進行處理。反之一樣。

二、上面是基於子線程中利用主線程提供的Handler發送消息出去,然後主線程的Looper從消息隊列中獲取並處理。那麼還有另外兩種情況:

1、主線程發送消息到子線程中;

採用的方法和前面類似。要在子線程中實例化AHandler並設定處理消息的方法,同時由於子線程沒有消息隊列和Looper的輪詢,所以要加上Looper.prepare(),Looper.loop()分別創建消息隊列和開啟輪詢。然後在主線程中使用該AHandler去發送消息即可。

2、子線程A與子線程B之間的通信。

1、 Handler為什麼能夠實現不同線程的通信?核心點在哪?

不同線程之間,每個線程擁有自己的Handler、消息隊列和Looper。Handler是公共的,線程可以通過使用目標線程的Handler對象來發送消息,這個消息會自動發送到所屬線程的消息隊列中去,線程自帶的Looper對象會不斷循環從裡面取出消息並把消息發送給Handler,回調自身Handler的handlerMessage方法,從而實現了消息的線程間傳遞。

2、 Handler的核心是一種事件激活式(類似傳遞一個中斷)的還是主要是用於傳遞大量數據的?重點在Message的內容,偏向於數據傳輸還是事件傳輸。

目前的理解,它所依賴的是消息隊列,發送的自然是消息,即類似事件中斷。

0、 Android消息處理機制(Handler、Looper、MessageQueue與Message)

1、 Handler、Looper源碼閱讀

2、 Android非同步消息處理機制完全解析,帶你從源碼的角度徹底理解

謝謝!

wingjay

![](https://avatars0.githubusercontent.com/u/9619875?v=3&s=460)

熱點內容
壓縮比英文 發布:2024-05-06 01:56:35 瀏覽:171
數字php 發布:2024-05-06 01:53:10 瀏覽:742
編程中怎麼 發布:2024-05-06 01:43:32 瀏覽:629
如何訪問遠程資料庫 發布:2024-05-06 01:39:20 瀏覽:447
刷演算法的網站 發布:2024-05-06 01:30:39 瀏覽:270
少兒編程徐州 發布:2024-05-06 01:20:42 瀏覽:462
sqlserver連接驅動 發布:2024-05-06 00:33:34 瀏覽:646
存儲開銷 發布:2024-05-06 00:13:38 瀏覽:954
伺服器怎麼盈利 發布:2024-05-05 23:56:16 瀏覽:942
java網站培訓學校 發布:2024-05-05 23:43:11 瀏覽:41