成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何調試Android Framework?

移動開發 Android
如果你仔細看完了本文和我給出的鏈接,那么應該對Debug技術不再陌生了;接下來你可以選擇Framework層的代碼,手動調試一下加深理解;在日后的工作過程中,不斷滴加強debug技術的練習,讓它稱為你解決復雜問題的條件反射,一定會事半功倍!

Linus有一句名言廣為人知:Read the fucking source code. 但其實,要深入理解某個軟件、框架或者系統的工作原理,僅僅「看」代碼是遠遠不夠的。就拿Android Framework來說,整個代碼量非常大不說,那些個動輒幾萬行的類如何去理解?所以我今天要說的就是:

Debug the fucking source code!!

之前分享過一個答案:大家遇到過什么 Android 兼容性問題?,這里面的有一些非常詭異的問題,我相信光靠看代碼你是永遠定位不出來的。還有我寫的一系列Android插件框架原理的文章,這里面涉及到大量Android Framework層的知識,有小伙伴會問,這些Framework層的原理,你是如何學習的呢,有訣竅嗎?有!那就是調試。

Debug是一項非常非常重要的技能,毋庸多言。今天我就給大家分享一下「調試Android Framework」的經驗,一旦掌握這項技能,那么Java層的任何問題都攔不住你了。

概覽

其實整個調試過程非常簡單:

  • 在你要調試進程的合適位置打上斷點
  • 跟蹤代碼(Step in/out/over等等)

在展開講述這兩方面之前,有必要先簡單了解下調試的基礎知識。Java平臺的調試是有一個規范化的標準的,那就是JPDA(Java Platform Debugger Architecture);通過 JPDA 提供的 API,開發人員可以方便靈活的搭建 Java 調試應用程序。 JPDA 主要由三個部分組成:Java 虛擬機工具接口(JVMTI),Java 調試線協議(JDWP),以及 Java 調試接口(JDI)。

Java程序的調試無非就是通過一個調試器(debugger)獲取對應Java虛擬機的信息,上文所述的JDWP就是調試器與虛擬機通信的橋梁。在dalvik虛擬機內部有一個專門的jdwp線程,Android系統的adbd進程通過socket與各個虛擬機的jdwp線程進行通信,外部調試器通過adb工具與adbd通信進而完成與jdwp的通信。我們通常所說的「attach debugger」指的就是這個意思——連接到指定的需要調試的進程。 

 

 

調試器工作原理 

調試器工作原理

如何在正確的地方下斷點

「正確的地方」包含兩個含義:首先,調試是以進程為單位進行的,如果你需要調試運行在進程A 中的代碼,卻把debugger attach到了B進程,那么這個斷點壓根兒就是牛頭不對馬嘴;另外呢,比如你想調試Android的多媒體框架,你得知道media相關的類在哪吧,也就是說需要在正確的函數里面下斷點。

如何在合適的進程下斷點?

如果是調試我們自己寫的App,在Android Studio里面非常簡單,在Run菜單de最后面有一個attach debugger to android process 的選項,點擊之后會出現一個菜單,選擇自己需要調試的進程即可;但是,如果需要調試Android Framework層的代碼,這樣做是達不到目的的——Framework層的代碼通常運行在別的進程(比如ActivityManagerService運行在system_server進程),而這些進程通常情況下是不可調試的,也就是說在attach debugger to android process 的那個菜單里面不會有系統的進程,如下圖: 

 

 

普通的無法調試的Android設備 

普通的無法調試的Android設備

為什么不可調試呢?上文我們簡要講述了調試器的工作原理,我們知道每一個虛擬機有一個jdwp線程,如果這個線程拒絕連接到調試器,你也就沒辦法對這個進程進行調試了。Android的所有App進程都是通過Zygote進程fork出來的,我們在android.os.Process這個類里面可以看到android進程的啟動過程有這么一句:

  1. if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) { 
  2.  
  3.     argsForZygote.add("--enable-debugger"); 
  4.  
  5.  

也就是說,一個進程是否可以調試是由進程啟動時候的參數決定的;普通的App進程如果是debug keystore默認是可以調試的,有或者你在AndroidManifest里面指定debuggable為true也是可以調試的。對系統進程,我們只有采取系統級別的手段:讓整個系統可以調試——debug版或者編譯參數debuggable為1的系統。

解決這個辦法很簡單:使用模擬器(真機也行,限Nexus系列刷原生Android系統,把系統啟動的debuggable參數修改為1),我的Nexus 5 可以調試的進程如下: 

 

 

可調試任意進程的設備 

可調試任意進程的設備

這樣,系統中所有的Android進程都可以調試了;這一點很重要,比如你要分析Activity的啟動流程,相當多一部分代碼是在ActivityManagerService所在的進程system_server執行的,如果你把斷點打在別的進程,就會產生跟丟了的情況。在比如,你要調試ActivityThread的main函數,在main函數里面執行了一句attach,最終調用AMS的attachApplication的時候,代碼就通過Binder IPC調用到了AMS的system_server進程。

明白你要執行的代碼運行在哪一個進程相當重要,在Android中,由于Binder通信機制的存在,「進程遷移」使用的非常非常頻繁,因此需要對binder機制有一定的了解;詳細的話可以參考我的博客:Binder學習指南

如何在對應的代碼處下斷點?

假設我們現在把debugger attach到了正確的進程,那么斷點應該下在哪里呢?直觀來講,就是說我需要導入所有的Android源碼嗎?如果不是應該導入哪些代碼,怎么導入?

首先,如果你需要調試的類在sdk里面導出了,你壓根兒就不需要再導入源碼,Android Studio自動幫你關聯了這部分代碼(前提是你用SDK Manager下載了sdk的源碼,如下圖: 

 

 

SDK manager下載源碼 

SDK manager下載源碼

比如你要調試ActivityManagerServce類的attachApplication方法,那么很簡單;創建一個空的Android項目,SDK版本選擇與你要調試的模擬器/真機 的android相同(這很重要,下文會講述);然后attrach 到system_server進程,直接在attach_application上面打上斷點;隨便啟動一個app,可以看到我們熟悉的調試界面: 

 

 

調試attachApplication 

調試attachApplication

如果這部分類在sdk中沒有導入(比如@hide)的,又或者壓根兒不是SDK的類,(比如系統app的源碼)那應該怎么辦呢?直接導入這部分代碼即可。不需要是Android項目,普通的Java項目即可;舉個例子,假設你想調試原生Android系統的「系統設置」這個程序,該如何做呢?

根據上面的分析,我們首先得知道「系統設置˜」運行在哪一個進程,通常情況下進程名字就是包名;我們查出設置的包名即可,而包名是在源碼的AndroidManifeist中聲明的,因此,我們找到「系統設置」這個程序的源碼即可;源碼在 https://android.googlesource.com/ ,系統App的源碼在/packages這個子目錄下面,我們一個個找,最終可以確定「系統設置」的源碼在https://android.googlesource.com/platform/packages/apps/Settings/ ;然后我們把這部分代碼git clone下來,導入Android Studio: 

 

 

調試Settings 

調試Settings

我們去AndroidManifest中查到,「系統設置」的包名為:com.android.settings,這樣我們attach到這個進程 : 

 

 

attach setting進程 

attach setting進程

然后,我們隨便打個斷點玩一玩,比如進入設置主界面的時候,斷下來;我們在AndroidManifest中查到設置程序的入口界面為:Settings,我們在這個類的onCreate里面打一個斷點,然后進入設置程序,發現完美滴斷下來了: 

 

 

在setting中斷點成功 

在setting中斷點成功

OK,到這里;應該學會如何在正確的位置打斷點了:正確的進程,正確的位置。接下來,要完成調試,還需要一些技巧。

如何跟蹤代碼?

或許你會說,跟蹤代碼不就是step in/out/over么,這有什么難的?但其實事情并沒有你想象的那么簡單,要優雅滴調試,還是需要一些姿勢的。

行號對應

跟蹤代碼一個首要的問題是行號對應。如果你在正確位置下了斷點,但是跟蹤的時候,單步調試,發現運行的代碼和Android Studio里面的代碼對不上號,那么就很蛋疼;要使得調試器的行號能夠對應,必須保證設備上的代碼和調試器的代碼是同一份;簡單來說,需要使用Android的原生系統(模擬器,Nexus系列真機),然后調試器里面使用的SDK版本,必須和設備的系統版本一致。

行號不對應怎么辦?

一定要注意行號對應這一點,這會使調試過程簡單很多;如果沒有辦法,行號對不上,那該如何調試呢?

行號不對應帶來的一個首要問題就是,下斷點的時候都有可能出現問題;比如你在TestClass的第100行下了一個斷點,但是由于行號不對應,有可能真正執行的代碼第100行是沒有意義的空行或者是在下一個函數里面,這樣斷點就沒有起到應有的作用了。

要解決行好對應的問題,必須使用方法斷點;我們直接在某個函數的入口設置斷點,這樣即使行號對不上,也能在正確的入口出斷下來,這一點非常重要。

解決了如何下斷點的問題,那么行號不對應,怎么知道執行到哪了,怎么查看局部變量?

觀察棧楨

在Android Studio的調試器的左邊,顯示了每一個線程執行的棧楨,棧楨里面包含了當前線程豐富的信息: 

 

 

觀察棧楨 

看到沒,真正運行的代碼在哪一行,當前運行的是什么函數一目了然;接下來你在step into/out的時候,不能以源代碼的行數為準,而應該以這個棧楨所顯示的代碼行數為準。

熟練使用斷點

OK,現在不論行號是否能對應,我們都能正確滴下斷點調試了。斷點有很多種類型,方法斷點,watch point,條件斷點都能夠很好滴輔助我們調試;如果你連這幾個名詞都沒有聽說過,一定要惡補一下;可以參閱我的博客:Android Studio你不知道的調試技巧;我就不再復述了。

如果你仔細看完了本文和我給出的鏈接,那么應該對Debug技術不再陌生了;接下來你可以選擇Framework層的代碼,手動調試一下加深理解;在日后的工作過程中,不斷滴加強debug技術的練習,讓它稱為你解決復雜問題的條件反射,一定會事半功倍!還有記住:

Debug the fucking source code.

責任編輯:龐桂玉 來源: 安卓開發精選
相關推薦

2010-01-06 18:59:41

.Net Framew

2012-02-20 14:41:30

JavaPlay Framew

2021-02-04 18:04:53

DbContext開源對象

2010-03-01 11:06:52

Python 調試器

2013-05-28 10:52:07

Android開發移動開發移動應用

2011-09-13 17:44:00

Eclipse And

2023-07-14 08:29:55

AOT.Net程序

2011-07-26 14:44:53

調試 Xcode

2021-03-30 11:33:45

云計算微服務云應用

2023-07-10 12:11:50

TypeScripChrome識別

2013-07-11 10:16:07

Android調試

2016-11-23 08:10:16

Android St JRebel調試神器

2010-01-06 15:56:18

.Net Framew

2019-11-13 15:40:00

Entity Fram審計數據數據庫

2021-06-21 09:00:00

Python代碼開發

2010-01-26 14:59:29

Android調試程序

2010-08-12 11:05:33

Flex數據綁定

2014-05-14 00:50:18

JoyentNode

2017-03-15 13:41:16

數據庫SQL調試

2017-09-12 15:11:12

Chrome
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色一级电影免费观看 | h片在线看| 久久久九九 | av一区二区三区四区 | 91激情视频| 久久久男人的天堂 | 99精品网 | 国产精品电影在线观看 | 99久久精品免费 | 国产精品久久精品 | 成人国产精品久久 | 欧美视频二区 | 中文字幕动漫成人 | 国产精品九九九 | 在线免费观看毛片 | 亚洲精品视频免费观看 | 国产a一区二区 | 成人天堂噜噜噜 | 久草在线在线精品观看 | 欧美日韩一卡 | 99精品久久久久久久 | 自拍 亚洲 欧美 老师 丝袜 | 视频一区二区国产 | 欧美精| 久久91av | 日本不卡一区二区三区 | 婷婷开心激情综合五月天 | 亚洲3级 | 日韩欧美一区二区在线播放 | 国产高清免费视频 | 亚洲成av | 成人午夜激情 | 激情a | 亚洲免费视频网址 | 欲色av| 国产草草视频 | 亚洲人成人一区二区在线观看 | 欧美视频在线一区 | 91文字幕巨乱亚洲香蕉 | 自拍视频一区二区三区 | 国产农村妇女毛片精品久久麻豆 |