Android WebView 研究筆記
記錄一下省的忘記了,遍看原始碼,邊猜測,邊實驗
chromedriver用了哪些命令和資源
目前Android WebView支援主要還是靠ChromeDriver來實現的。
Chromedriver貌似一定要ADB才行。其中用到了命令有 ps
, grep
, adb forward
, am start
等等
來源: ofollow,noindex" target="_blank">https://github.com/bayandin/chromedriver/blob/907b958e09dbfdafb13e9257b181009d0ab43b4a/chrome/adb_impl.cc
既然還用到了 adb forward .. localabstract
, 先開啟一個帶webview的app(這裡用了微信)
檢視下有哪些服務監聽了localabstract
$ cat /proc/net/unix | grep @ 0000000000000000: 00000002 00000000 00010000 0001 01 32803 @bthcitraffic 0000000000000000: 00000002 00000000 00010000 0001 01 3789231 @chrome_devtools_remote 0000000000000000: 00000002 00000000 00010000 0001 01 32963 @/data/misc/bluedroid/.a2dp_ctrl 0000000000000000: 00000002 00000000 00010000 0001 0176 @time_genoff 0000000000000000: 00000002 00000000 00010000 0001 0188 @android:debuggerd 0000000000000000: 00000002 00000000 00010000 0001 01 4640516 @webview_devtools_remote_13680 0000000000000000: 00000002 00000000 00010000 0001 01 17596 @jdwp-control 0000000000000000: 00000003 00000000 00000000 0001 03 4453235 @jdwp-control 0000000000000000: 00000003 00000000 00000000 0001 03 4250761 @jdwp-control
其中 @
符號程式碼監聽的本地Unix socket
這裡看到有兩個 @chrome_devtools_remote
和 @webview_devtools_remote_13680
比較吸引人。
chrome_devtools_remote
應該對應的是瀏覽器。
webview_devtools_remote_13680
對應的應該是應用內的WebView,根據原始碼感覺這個13680應該是個pid
odin:/ $ ps | grep 13680 USERPIDPPIDVSIZERSSWCHANPCNAME u0_a28013680 5912522104 168072 SyS_epoll_ 0000000000 S com.tencent.mm:tools
com.tencent.mm
這個應該就是微信了。
先把這個forward到本地
$ adb forward tcp:5000 localabstract:webview_devtools_remote_13680
看chromedriver的程式碼,裡面自帶一些http介面,具體看下面的程式碼
https://github.com/bayandin/chromedriver/blob/33218feb63bc972c7175390ee2302fe5a2f25056/chrome/devtools_http_client.cc#L92有個比較簡單的介面獲取瀏覽器的版本號,以此來確定該使用的chromedriver版本。
$ curl localhost:5000/json/version { "Android-Package": "com.tencent.mm", "Browser": "Chrome/57.0.2987.132", "Protocol-Version": "1.2", "User-Agent": "Mozilla/5.0 (Linux; Android 7.1.1; OD103 Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044205 Mobile Safari/537.36", "V8-Version": "5.7.492.72", "WebKit-Version": "537.36 (@user1128ad40ab2e3d761c06d1)" }
從這個連結裡面可以看到沒有Chrome Version( 57 )對應的應該使用的chromedriver版本號( 2.29 ) https://chromedriver.storage.googleapis.com/2.41/notes.txt

去這個地址下載 https://npm.taobao.org/mirrors/chromedriver
繼續更新
猜測:除了微信有個除錯的按鈕,其他的H5的應用應該也是可以的吧。
先試了試Appium自帶的demo apk
安裝到手機上之後,進入 Views
-> WebView
,然後看到這麼一個簡單的介面

圖層結構顯示也有Hierarchy

Chrome瀏覽器開啟 chrome://inspect

更多相關的內容參考谷歌的Chrome-Devtools文件 https://developers.google.com/web/tools/chrome-devtools/remote-debugging/?hl=zh-cn
使用VXP強制開始WebView
那有沒有強制開啟的方法呢? 很快谷歌出來一篇文章
強制開啟android webview debug模式使用Chrome inspect看來手機需要Root才行,還用到了高階的Xposed(不對呀,我明明記得可以不用root的呀),繼續谷歌了下發現還有個VirtualXposed可以不用root
相關的VirtualXposed(簡稱VXP)簡介 https://github.com/android-hacker/VirtualXposed
安裝很簡單,跟普通的App一樣,下載apk到手機,安裝就ok了。
接下來用VXP自帶的安裝器,安裝 ApiDemos-debug.apk
然後再安裝個外掛 WebViewDebugHook 同樣是個Apk下載,用VXP安裝上就好了。
關於那個外掛的原理可以在這裡看到 https://www.jianshu.com/p/d6699cd4505e
安裝上之後,先開啟

進入到 模組 中,勾選

返回,然後向下滑動,進入到這個介面,點選箭頭位置

拖到最下面點選 重啟
是外掛更改生效。
PS: 使用VXP安裝的應用 pm list packages
是看不到的,只有在執行的時候用 ps
才可以檢視到
應用使用的Chrome版本是 62.0.3202.84
Appium的程式碼裡面有個對應的表可以直接查改用哪一個 chromedriver https://github.com/appium/appium-chromedriver/blob/master/lib/chromedriver.js#L20
PS D:\Temp> .\chromedriver.exe -h Usage: D:\Temp\chromedriver.exe [OPTIONS] Options --port=PORTport to listen on --adb-port=PORTadb server port --log-path=FILEwrite server log to file instead of stderr, increases log level to INFO --log-level=LEVELset log level: ALL, DEBUG, INFO, WARNING, SEVERE, OFF --verboselog verbosely (equivalent to --log-level=ALL) --silentlog nothing (equivalent to --log-level=OFF) --versionprint the version number and exit --url-basebase URL path prefix for commands, e.g. wd/url --whitelisted-ipscomma-separated whitelist of remote IPv4 addresses which are allowed to connect to Chr omeDriver
chromedriver預設監聽9515埠。
先來段簡單的程式碼試試。獲取WebView中顯示的內容

# coding: utf-8 from selenium import webdriver options = {'androidPackage': 'com.appium.android.apis', 'androidUseRunningApp': True} d = webdriver.Remote("http://localhost:9515", {"chromeOptions": options}) # /html/body/a el = d.find_element_by_xpath("/html/body/a") print(el.text)
執行,之後就報錯了,提示
WebDriverException: Message: unknown error: com.appium.android.apis is not installed on device 3578298f (Driver info: chromedriver=2.41.578737 (49da6702b16031c40d63e5618de03a32ff6c197e),platform=Windows NT 10.0.16299 x86_6 4)
估計是通過 pm path <package)name>
判斷的有沒有安裝,也罷,再安裝一遍好了。然後給options加了 androidProcess
引數
options = { 'androidPackage': 'io.appium.android.apis', 'androidUseRunningApp': True, 'androidProcess': 'io.appium.android.apis' }
重新再執行程式碼終於出來了
Hello World! - 1
哎,真是麻煩。。 -~~
參考
- chromedriver官方簡短的使用說明
- 微信 webview 的自動化技術
- chromedriver原始碼
- ATX 文件 - Android WebView 支援說明
- ATX-uiautomator2 實現 webview 的操作
- 使用Xposed強制android WebView開啟debug模式
- 谷歌文件-遠端除錯 WebView
- Appium的chromedriver庫 https://github.com/appium/appium-chromedriver
- NB的VXP專案 https://github.com/android-hacker/VirtualXposed
- 通過ADB控制VXP
- Chromedriver淘寶映象