很久以來,我一直想找一種方法來斷點
調試安卓系統自身的Service,或者bind類型的Service,比如我想看WifiManager里面的getWifiApConfiguration函數是如何實現的。從代碼看到:
public WifiConfiguration getWifiApConfiguration() {
try {
return mService.getWifiApConfiguration();
} catch (RemoteException e) {
return null;
}
}
它直接調用的是一個mService的變量。而這個東西是一個實現了IWifiManager的接口的類。在我自己的應用里無法用斷點命中它,雖然我能找到它的真實實現是在/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java 中。
今天,感謝這篇文章:
終於找到了斷點
調試系統Service的方法:
1. 首先獲得一份Service的源代碼。比如/frameworks/base/services/accessibility.
2. 在Android Studio中,導入工程->Create project from existing sources,然后是選擇要添加到項目根目錄的目錄,選擇libraries,選擇Modules,選擇SDK,一路NEXT即可. 現在,代碼被添加進來了,盡管缺少需要的類庫,顯示全是錯誤,但是沒關系,不影響調試。
3. 在Run菜單中,選擇Edit configurations,添加一個Remote類型的
調試。端口號默認的是5005,你可以修改成你需要的任意值。比如可以設置成9999

4. 用 adb shell ps | grep system_server 找出Accessibility Service所在的進程,這里是 548
system 548 195 1716200 121628 ffffffff b6e855d8 S system_server
5. 同時,用adb jdwp確保548是可以調試的。這一步只是用來看一下,不是必需。
6. adb forward tcp:9999 jdwp:548 這是最關鍵的一步了,把本機的9999端口轉向遠端機的jdwp 548端口。這里,9999是你剛才設置的調試配置中的端口。Android Studio會在調試開始時在本地的這個端口上監聽。也就相當於在 jdwp 548端口監聽了。
7. 在android Studio中運行這個debug。當service相關函數被調用到的時候,會發現斷點命中。
如果你要調試的應用還沒有運行起來,比如,是你自己的應用。你可以在開發者選項里面選擇它為 調試應用,或者通過 adb shell am set-debug-app -w <包名> 來設置它在運行起來之后等待調試器。然后它會等待調試器掛載,你在進行上述動作。
好了,現在基本所有的系統級別的Java都能斷點調試了,看起代碼來應該更容易了。