A preface
In the process of WebView loading web pages, sometimes the page cannot be loaded, as follows:
So how do you know if the page is loading incorrectly?
Ii. Solutions
webview.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView? , url:String?). {
super.onPageFinished(view, url)
Log.d(TAG, "onPageFinished: ")}override fun onReceivedError(
view: WebView? , request:WebResourceRequest? , error:WebResourceError?). {
super.onReceivedError(view, request, error)
Log.d(TAG, "onReceivedError: request= " + request.json())
Log.d(TAG, "onReceivedError: error= " + error.json())
}
}
webview.loadUrl("https://www.baidu.com/")
Copy the code
Request output:
{” a “: {” a” : “www.baidu.com/”, “b” : true,… (Linux; Android 11; Sdk_gphone_x86_arm Build/RSR1.200819.001. A1; Wv) AppleWebKit / 537.36 (KHTML, Like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari / 537.36 “, “Accept”, “text/HTML and application/XHTML + XML, application/XML. Q \ u003d0. 9, image/webp, image/apng, /; Q \ u003d0. 8, application/signed – exchange; v\u003db3; Q \ u003d0. 9, “” Upgrade – Insecure – Requests” : “1”}}}
The error output:
{“a”:{“a”:-1,”b”:”net::ERR_CACHE_MISS”}}
/** * Note that, unlike the old version, the new version already calls back *(iframe, image, etc.) for all resource loading errors, not just the loaded main page */
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
if(request.isForMainFrame()) { onReceivedError(view, error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString()); }}Copy the code
Therefore, through the above monitoring, you can know the corresponding error content, and then do the corresponding service processing.
Common error case analysis
1. Error: ERR_UNKNOWN_URL_SCHEME
Reappearance condition: open baidu news and information page, and click comment
The carrier | The phenomenon of |
---|---|
Built-in App WebView | Error: ERR_UNKNOWN_URL_SCHEME |
UC and Huawei browsers | Stay in the current page state |
Chrome | Jump to baidu APP inside open |
ShouldOverrideUrlLoading:
{“a”:{“a”:”baiduboxapp://v1/easybrowse/hybrid? upgrade\u003d1\u0026type\u003dhybrid\u0026tpl_id\u003dlanding_app.html\u0026newbrowser\u003d1\u0026style\u003d%7B%22tool baricons%22%3A%7B%22tids%22%3A%5B%224%22%2C%221%22%2C%222%22%2C%223%22%5D%2C%22menumode%22%3A%222%22%2C%22actionBarConfi g%22%3A%7B%22extCase%22%3A%220%22%7D%7D%7D\u0026slog\u003d%7B%22from%22%3A%22feed%22%7D\u0026context\u003d%7B%22nid%22%3 A%22news_9777178803801641010%22%7D\u0026ch_url\u003dhttps%3A%2F%2Fmbd.baidu.com%2Fnewspage%2Fdata%2Flandingreact%3FpageT ype%3D2%26nid%3Dnews_9777178803801641010%26uk%3D%26sourceFrom%3DlandingShare\u0026commentInfo\u003d%7B%22topic_id%22%3A1 066000039731532%2C%22opentype%22%3A2%7D\u0026logargs\u003d%7B%22source%22%3A%221020283l%22%2C%22channel%22%3A%221020283m %22%7D\u0026needlog\u003d1″,”b”:false,”c”:true,”d”:false,”e”:”GET”,”f”:{“Accept”:”text/html,application/xhtml+xml,applic ation/xml; Q \ u003d0. 9, image/avif, image/webp image/apng, /; Q \ u003d0. 8, application/signed – exchange; v\u003db3; Q \ u003d0. 9, “” Referer” : “mbd.baidu.com/newspage/da…
It can be found that the protocol does not start with HTTP class, but with baiduboxapp defined by baidu itself. Therefore, do not do processing, of course, is not recognized.
2. Implement UC and Huawei browser processing effect — > Ignore
webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView? , request:WebResourceRequest?).: Boolean {
Log.d(TAG, "shouldOverrideUrlLoading: ${request.json()}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Log.d(TAG, "shouldOverrideUrlLoading: url->${request? .url}")
if(view ! =null&& request? .url? .toString() ! =null) {
if (request.url.toString().startsWith("http")) {
view.loadUrl(request.url.toString())
}
return true
}
Copy the code
3. How to achieve the effect of Chrome browser processing — > can jump
Assuming that this is the effect of Baidu adaptation of Chrome, rather than Chrome actively to baidu code page, then shows that the client WebView can also do so.
With this in mind, let’s urldecode the protocol to see what’s special about Request:
baiduboxapp://v1/easybrowse/hybrid? upgrade=1&type=hybrid&tpl_id=landing_app.html&newbrowser=1&style={“toolbaricons”:{“tids”:[“4″,”1″,”2″,”3″],”menumode”:”2 “,”actionBarConfig”:{“extCase”:”0″}}}&slog={“from”:”feed”}&context={“nid”:”news_9777178803801641010″}&ch_url=mbd.baidu.c Om/newspage/da…
Overall, it still conforms to URI rules. In this case, consider using Intent handling.
webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView? , request:WebResourceRequest?).: Boolean {
Log.d(TAG, "shouldOverrideUrlLoading: ${request.json()}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Log.d(TAG, "shouldOverrideUrlLoading: url->${request? .url}")
if(view ! =null&& request? .url? .toString() ! =null) {
if (request.url.toString().startsWith("http")) {
view.loadUrl(request.url.toString())
} else {
try {
Log.d(TAG, "ShouldOverrideUrlLoading: began to jump")
startActivity(Intent(Intent.ACTION_VIEW, request.url))
} catch (e: Exception) {
Log.d(TAG, "shouldOverrideUrlLoading: ${e.json()}")}}}}return true
}
Copy the code
Run and view the result as follows:
From the results, it can jump to baidu App, assuming true. For non-HTTP protocol addresses, you can use startActivity(Intent(intent.action_view, request.url)) to handle protocol content.
Four summarizes
Finally, make the agreement and deal with it according to your own business. After all, not everyone wants their users to jump out of their App.