問題情境:在調試某個應用時,需要監控應用與伺服器之間的HTTP通訊.
解決思路:第一時間想到Fiddler2.Android官方文檔提到用TCPDump獲得通訊封包或即時監控,好是好,有點高射炮打蚊子的意思.Fiddler2這個工具,介面友好,功能足夠使用,可以說是Windows上最好的HTTP監控工具.Fiddler2用起來很方便,運行之後,即在本機建立一個代理(預設設定為127.0.0.1:8888),其他訪問HTTP的應用程式,把代理設為同一地址和連接埠即可.
實施過程:
按照文檔的指導,在啟動模擬器時,使用 -http-proxy參數,設定127.0.0.1:8888為模擬器的上網代理,結果失敗.Fiddler2沒有抓到通訊應答.
解決方案:
再細讀文檔中有關模擬器的部分,看到Network Address Space一段,忽有所悟.這段文字是這麼寫的
模擬器在虛擬路由器/防火牆服務後面運行,這套路由器/防火牆服務隔離於開發機的網路介面、設定,也與互連網相隔離.類比裝置不能訪問開發機或網路上的其他模擬器.它看到的只是自己通過乙太網路串連到一個路由器/防火牆.
這下清楚了,模擬器壓根不知道127.0.0.1是個啥地址,也壓根訪問不到.在127.0.0.1上設定的代理,自然也抓不到任何通訊應答了.文檔接著寫道,這個虛擬防火牆/路由器管理從10.0.2.2至10.0.2.24,模擬器的IP地址是10.0.2.15,而模擬器看到的開發機地址則是10.0.2.2.也就是說,從模擬器的立場看,Fiddler2是在10.0.2.2上啟動並執行.
於是用emulator命令加上avd -http-proxy 10.0.2.2:8888參數啟動模擬器,在模擬器上運行browser,訪問任何web地址,可以看到,Fiddler2抓到了HTTP通訊:
java代碼:
- private HttpURLConnection createConnection(URL url){
- HttpURLConnection conn=null;
- try {
- conn=(HttpURLConnection)url.openConnection();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return conn;
- }
複製代碼
這次Fiddler2沒能抓到通訊。但應用程式訪問網頁是成功的。只在啟動模擬器時加上-http-proxy參數還不夠,應用程式建立串連時,也要指定HTTP代理才行:
java代碼:
- private HttpURLConnection createConnectionWithProxy(URL url, String proxyAddress, int proxyPort) {
- HttpURLConnection conn = null;
- Proxy proxy=new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress,proxyPort));
- try {
- conn = (HttpURLConnection) url.openConnection(proxy);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return conn;
- }
複製代碼