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.