Android WebView 診斷與排查問題的方法和技巧

0
回復
356
查看
打印 上一主題 下一主題
[復制鏈接]

40

主題

60

帖子

3388

安幣

管理員

Rank: 9Rank: 9Rank: 9

樓主
發表于 2020-5-6 16:00:01 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
如果對本篇文章感興趣,請前往,原文地址:http://www.1574304.live/blog-720372-84012.html

WebView,是安卓中很重要的一個組件,我們的應用中集成WebView后,可能會遇到各種各樣的問題,這里簡單介紹一些Android WebView 診斷與排查問題的方法,希望對于大家有這方面的問題的朋友有所幫助。
開啟DiagnosableWebViewClient日志輸出

[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3[color=#93A1A1 !important]4[color=#93A1A1 !important]5[color=#93A1A1 !important]6[color=#93A1A1 !important]7[color=#93A1A1 !important]8[color=#93A1A1 !important]9[color=#93A1A1 !important]10[color=#93A1A1 !important]11[color=#93A1A1 !important]12[color=#93A1A1 !important]13[color=#93A1A1 !important]14[color=#93A1A1 !important]15[color=#93A1A1 !important]16[color=#93A1A1 !important]17[color=#93A1A1 !important]18[color=#93A1A1 !important]19[color=#93A1A1 !important]20[color=#93A1A1 !important]21[color=#93A1A1 !important]22[color=#93A1A1 !important]23[color=#93A1A1 !important]24[color=#93A1A1 !important]25[color=#93A1A1 !important]26[color=#93A1A1 !important]27[color=#93A1A1 !important]28[color=#93A1A1 !important]29[color=#93A1A1 !important]30[color=#93A1A1 !important]31[color=#93A1A1 !important]32[color=#93A1A1 !important]33[color=#93A1A1 !important]34[color=#93A1A1 !important]35[color=#93A1A1 !important]36[color=#93A1A1 !important]37[color=#93A1A1 !important]38[color=#93A1A1 !important]39[color=#93A1A1 !important]40[color=#93A1A1 !important]41[color=#93A1A1 !important]42[color=#CB4B16 !important]package [color=#B58900 !important]com.droidyue.webview.webviewclient[color=#268BD2 !important]import [color=#268BD2 !important]android.[color=#268BD2 !important]net.[color=#268BD2 !important]http.[color=#268BD2 !important]SslError[color=#268BD2 !important]import [color=#268BD2 !important]android.[color=#268BD2 !important]webkit.*[color=#268BD2 !important]import [color=#268BD2 !important]com.[color=#268BD2 !important]droidyue.[color=#268BD2 !important]common.[color=#268BD2 !important]debugMessage[color=#268BD2 !important]import [color=#268BD2 !important]com.[color=#268BD2 !important]droidyue.[color=#268BD2 !important]webview.[color=#268BD2 !important]ext.[color=#268BD2 !important]toSimpleString[color=#93A1A1 !important]/**[color=#93A1A1 !important] * 診斷(錯誤信息)的WebViewClient,會以日志輸出形式輸出錯誤信息,便于發現網頁的問題[color=#93A1A1 !important] */[color=#268BD2 !important]open [color=#CB4B16 !important]class [color=#D33682 !important]DiagnosableWebViewClient : [color=#268BD2 !important]WebViewClient() {    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onReceivedError([color=#268BD2 !important]view: [color=#268BD2 !important]WebView?, [color=#268BD2 !important]errorCode: [color=#268BD2 !important]Int, [color=#268BD2 !important]description: [color=#268BD2 !important]String?, [color=#268BD2 !important]failingUrl: [color=#268BD2 !important]String?) {        [color=#268BD2 !important]super.[color=#268BD2 !important]onReceivedError([color=#268BD2 !important]view, [color=#268BD2 !important]errorCode, [color=#268BD2 !important]description, [color=#268BD2 !important]failingUrl)        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onReceivedError", [color=#2AA198 !important]"errorCode", [color=#268BD2 !important]errorCode, [color=#2AA198 !important]"description", [color=#268BD2 !important]description,            [color=#2AA198 !important]"failingUrl", [color=#268BD2 !important]failingUrl, [color=#2AA198 !important]"webview.info", [color=#268BD2 !important]view?.[color=#268BD2 !important]toSimpleString())    }    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onReceivedError([color=#268BD2 !important]view: [color=#268BD2 !important]WebView?, [color=#268BD2 !important]request: [color=#268BD2 !important]WebResourceRequest?, [color=#268BD2 !important]error: [color=#268BD2 !important]WebResourceError?) {        [color=#268BD2 !important]super.[color=#268BD2 !important]onReceivedError([color=#268BD2 !important]view, [color=#268BD2 !important]request, [color=#268BD2 !important]error)        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onReceivedError", [color=#2AA198 !important]"request", [color=#268BD2 !important]request?.[color=#268BD2 !important]toSimpleString(), [color=#2AA198 !important]"error", [color=#268BD2 !important]error?.[color=#268BD2 !important]toSimpleString(),            [color=#2AA198 !important]"webview.info", [color=#268BD2 !important]view?.[color=#268BD2 !important]toSimpleString())    }    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onSafeBrowsingHit([color=#268BD2 !important]view: [color=#268BD2 !important]WebView?, [color=#268BD2 !important]request: [color=#268BD2 !important]WebResourceRequest?, [color=#268BD2 !important]threatType: [color=#268BD2 !important]Int, [color=#268BD2 !important]callback: [color=#268BD2 !important]SafeBrowsingResponse?) {        [color=#268BD2 !important]super.[color=#268BD2 !important]onSafeBrowsingHit([color=#268BD2 !important]view, [color=#268BD2 !important]request, [color=#268BD2 !important]threatType, [color=#268BD2 !important]callback)        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onSafeBrowsingHit", [color=#2AA198 !important]"request", [color=#268BD2 !important]request?.[color=#268BD2 !important]toSimpleString(), [color=#2AA198 !important]"threatType", [color=#268BD2 !important]threatType,            [color=#2AA198 !important]"webview.info", [color=#268BD2 !important]view?.[color=#268BD2 !important]toSimpleString())    }    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onReceivedHttpError([color=#268BD2 !important]view: [color=#268BD2 !important]WebView?, [color=#268BD2 !important]request: [color=#268BD2 !important]WebResourceRequest?, [color=#268BD2 !important]errorResponse: [color=#268BD2 !important]WebResourceResponse?) {        [color=#268BD2 !important]super.[color=#268BD2 !important]onReceivedHttpError([color=#268BD2 !important]view, [color=#268BD2 !important]request, [color=#268BD2 !important]errorResponse)        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onReceivedHttpError", [color=#2AA198 !important]"request", [color=#268BD2 !important]request, [color=#2AA198 !important]"errorResponse", [color=#268BD2 !important]errorResponse?.[color=#268BD2 !important]toSimpleString(),            [color=#2AA198 !important]"webview.info", [color=#268BD2 !important]view?.[color=#268BD2 !important]toSimpleString())    }    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onReceivedSslError([color=#268BD2 !important]view: [color=#268BD2 !important]WebView?, [color=#268BD2 !important]handler: [color=#268BD2 !important]SslErrorHandler?, [color=#268BD2 !important]error: [color=#268BD2 !important]SslError?) {        [color=#268BD2 !important]super.[color=#268BD2 !important]onReceivedSslError([color=#268BD2 !important]view, [color=#268BD2 !important]handler, [color=#268BD2 !important]error)        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onReceivedSslError", [color=#2AA198 !important]"error", [color=#268BD2 !important]error, [color=#2AA198 !important]"webview.info", [color=#268BD2 !important]view?.[color=#268BD2 !important]toSimpleString())    }}

舉個例子

WebView頁面出現了白屏,不展示任何內容,如下圖

利用上面支持的內容,我們查看錯誤輸出日志
[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3D debugMessage: ConcreteWebViewClient;onReceivedSslError error primary error: 3 certificate: Issued to: [color=#268BD2 !important]CN=sni.cloudflaressl.com,O=Cloudflare[color=#DC322F !important]\, Inc.,L=San Francisco,ST=CA,C=US;D debugMessage: Issued by: [color=#268BD2 !important]C=NZ,ST=Auckland,L=Auckland,O=XK72 Ltd,OU=https://charlesproxy.com/ssl,CN=Charles Proxy CA (4 Sep 2018[color=#DC322F !important]\, bogon);D debugMessage:  on URL: https://droidyue.com/ webview.info [color=#268BD2 !important]url=https://droidyue.com/;originalUrl=null

通過查找源碼(SslError.java)我們了解到

  • errorCode 為 3,代表證書不信任。
這其中的緣由是

  • 我們在設備上安裝的charles證書,屬于用戶添加的證書
  • 出于應用安全的目的,Android 7及之后默認不信任用戶添加的證書(Android 7 之前是默認信任用戶添加的證書)
  • 當我們將App的編譯目標提到24及其以上,系統就會激活這一安全限制。
所以,我們按照這篇文章解決Android手機連接Charles Unknown問題的方案,允許App在debug版本下信任用戶證書就可以解決問題了。
Console日志查看

比如,我們有這樣一段Javascript代碼處理console輸出。
[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3[color=#93A1A1 !important]4[color=#93A1A1 !important]5[color=#B58900 !important]console.[color=#B58900 !important]debug([color=#2AA198 !important]"console.debug");[color=#B58900 !important]console.[color=#B58900 !important]log([color=#2AA198 !important]"console.log");[color=#B58900 !important]console.[color=#B58900 !important]info([color=#2AA198 !important]"console.info");[color=#B58900 !important]console.[color=#B58900 !important]warn([color=#2AA198 !important]"console.warn");[color=#B58900 !important]console.[color=#B58900 !important]error([color=#2AA198 !important]"console.error")

我們使用
[color=#93A1A1 !important]1adb logcat | grep [color=#2AA198 !important]"chromium" --line-buffered --color=always | grep CONSOLE --color=always

可以過濾出WebView CONSOLE的日志輸出
[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3[color=#93A1A1 !important]4[color=#93A1A1 !important]5 I chromium: [INFO:CONSOLE(2)] [color=#2AA198 !important]"console.debug", [color=#859900 !important]source:  (2) I chromium: [INFO:CONSOLE(3)] [color=#2AA198 !important]"console.log", [color=#859900 !important]source:  (3) I chromium: [INFO:CONSOLE(4)] [color=#2AA198 !important]"console.info", [color=#859900 !important]source:  (4) I chromium: [INFO:CONSOLE(5)] [color=#2AA198 !important]"console.warn", [color=#859900 !important]source:  (5) I chromium: [INFO:CONSOLE(6)] [color=#2AA198 !important]"console.error", [color=#859900 !important]source:  (6)

但是這樣也有一個不足,就是沒有打印出Console的消息級別(都展示成了INFO:CONSOLE)。
如果想要解決上面的不足或者自定義日志輸出關鍵字的話,可以重寫實現WebChromeClient的onConsoleMessage方法
[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3[color=#93A1A1 !important]4[color=#93A1A1 !important]5[color=#93A1A1 !important]6[color=#93A1A1 !important]7[color=#93A1A1 !important]8[color=#93A1A1 !important]9[color=#93A1A1 !important]10[color=#93A1A1 !important]11[color=#93A1A1 !important]12[color=#93A1A1 !important]13[color=#93A1A1 !important]14[color=#93A1A1 !important]15[color=#93A1A1 !important]16[color=#93A1A1 !important]17[color=#93A1A1 !important]18[color=#93A1A1 !important]19[color=#CB4B16 !important]package [color=#B58900 !important]com.droidyue.webview.chromeclient[color=#268BD2 !important]import [color=#268BD2 !important]android.[color=#268BD2 !important]webkit.[color=#268BD2 !important]ConsoleMessage[color=#268BD2 !important]import [color=#268BD2 !important]android.[color=#268BD2 !important]webkit.[color=#268BD2 !important]WebChromeClient[color=#268BD2 !important]import [color=#268BD2 !important]com.[color=#268BD2 !important]droidyue.[color=#268BD2 !important]common.[color=#268BD2 !important]debugMessage[color=#268BD2 !important]import [color=#268BD2 !important]com.[color=#268BD2 !important]droidyue.[color=#268BD2 !important]webview.[color=#268BD2 !important]ext.[color=#268BD2 !important]toSimpleString[color=#268BD2 !important]open [color=#CB4B16 !important]class [color=#D33682 !important]DiagnosableChromeClient: [color=#268BD2 !important]WebChromeClient() {    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onConsoleMessage([color=#268BD2 !important]message: [color=#268BD2 !important]String?, [color=#268BD2 !important]lineNumber: [color=#268BD2 !important]Int, [color=#268BD2 !important]sourceID: [color=#268BD2 !important]String?) {        [color=#93A1A1 !important]//不需要調用super方法        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onConsoleMessage", [color=#2AA198 !important]"message", [color=#268BD2 !important]message, [color=#2AA198 !important]"lineNumber", [color=#268BD2 !important]lineNumber, [color=#2AA198 !important]"sourceID", [color=#268BD2 !important]sourceID)    }    [color=#CB4B16 !important]override [color=#CB4B16 !important]fun [color=#268BD2 !important]onConsoleMessage([color=#268BD2 !important]consoleMessage: [color=#268BD2 !important]ConsoleMessage?): [color=#268BD2 !important]Boolean {        [color=#268BD2 !important]debugMessage([color=#2AA198 !important]"onConsoleMessage", [color=#2AA198 !important]"message", [color=#268BD2 !important]consoleMessage?.[color=#268BD2 !important]toSimpleString())        [color=#93A1A1 !important]//返回true,不再需要webview內部處理        [color=#CB4B16 !important]return [color=#CB4B16 !important]true    }}

[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3[color=#93A1A1 !important]4[color=#93A1A1 !important]5D debugMessage: ConcreteWebChromeClient;onConsoleMessage message [color=#268BD2 !important]messageLevel=TIP;message=console.debug;sourceId=;[color=#268BD2 !important]lineNumber=1D debugMessage: ConcreteWebChromeClient;onConsoleMessage message [color=#268BD2 !important]messageLevel=LOG;message=console.log;sourceId=;[color=#268BD2 !important]lineNumber=2D debugMessage: ConcreteWebChromeClient;onConsoleMessage message [color=#268BD2 !important]messageLevel=LOG;message=console.info;sourceId=;[color=#268BD2 !important]lineNumber=3D debugMessage: ConcreteWebChromeClient;onConsoleMessage message [color=#268BD2 !important]messageLevel=WARNING;message=console.warn;sourceId=;[color=#268BD2 !important]lineNumber=4D debugMessage: ConcreteWebChromeClient;onConsoleMessage message [color=#268BD2 !important]messageLevel=ERROR;message=console.error;sourceId=;[color=#268BD2 !important]lineNumber=5

開啟 WebView 遠程調試

從Android Kitkat(4.4)開始,WebView 支持與Chrome 連接執行遠程調試。
開啟很簡單,如下代碼
[color=#93A1A1 !important]1[color=#93A1A1 !important]2[color=#93A1A1 !important]3[color=#93A1A1 !important]4[color=#93A1A1 !important]5[color=#CB4B16 !important]fun [color=#268BD2 !important]WebView.[color=#268BD2 !important]enableRemoteDebugging() {    [color=#CB4B16 !important]if ([color=#268BD2 !important]Build.[color=#268BD2 !important]VERSION.[color=#268BD2 !important]SDK_INT >= [color=#268BD2 !important]Build.[color=#268BD2 !important]VERSION_CODES.[color=#268BD2 !important]KITKAT && [color=#268BD2 !important]BuildConfig.[color=#268BD2 !important]DEBUG) {        [color=#268BD2 !important]WebView.[color=#268BD2 !important]setWebContentsDebuggingEnabled([color=#CB4B16 !important]true)    }}

但需要注意兩點

  • 一定要限定運行設備大于等于4.4系統
  • 強烈建議限定在Debug編譯(或等同條件)包下開啟,不建議Release包也啟用該功能
配置完成后,啟動App,打開Chrome,輸入chrome://inspect
可以調試的功能有

  • 審查元素
  • 執行Javascript
  • 查看網頁資源
  • 進行性能分析
  • 其他功能
  繼續閱讀全文



想在安卓巴士找到更多優質博文,可移步博客區

如果對本篇文章感興趣,請前往,
原文地址:
http://www.1574304.live/blog-720372-84012.html
分享到:  QQ好友和群 QQ空間 微信
收藏
收藏0
支持
支持0
反對
反對0
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

領先的中文移動開發者社區
18620764416
7*24全天服務
意見反饋:[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )

在柳州学什么小吃赚钱 网赌输了怎样找客服退钱 天津11选五开奖结果32期 极速电玩捕鱼安卓版 通化大嘴棋牌官网 福彩3d开机号今日 陕西快乐10分推荐 上海11选五走势图一定牛 国内十大期货配资公司 最精准的一波中特公式 甘肃11选5真准网