Android WebView加载淘宝拼多多及其他第三方页面问题

阔别Android一年多,最近又接手过来公司里的Android端的项目,按照需求如果手机中没有安装淘宝或者拼多多、京东及其他app应用就在应用内使用webview加载第三方应用页面,但是一直错误重定向或者打不开页面,看了很多篇文章最后筛选组合起来终于解决了,下面是具体问题与解决方法

加载第三方应用页面问题

  1. 如图所示使用WebView加载京东的页面(https://u.jd.com/g4SHnM),直接显示白屏了
    Android WebView加载淘宝拼多多及其他第三方页面问题_第1张图片

  2. 当访问拼多多一商品(https://p.pinduoduo.com/cnH9JxxZ)页面的时候会出现下面图片的重定向问题
    Android WebView加载淘宝拼多多及其他第三方页面问题_第2张图片


问题解决

原因一
  • 根据控制台输出的日志可以看出是因为webview无法加载HTTPS协议的页面。
"Mixed Content: The page at 'https://u.jd.com/g4SHnM' was loaded over HTTPS, but requested an insecure favicon 'http://www.jd.com/'. This request has been blocked; the content must be served over HTTPS.", source: https://u.jd.com/g4SHnM (0)

HTTPs页面加载不出来的主要原因是SSL证书不能被正确识别,这里要做的,就是重载WebViewClient中的OnReceiveSslError方法:

	@Override
	public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
	              handler.proceed();
	}

这样,当收到证书错误时,忽略掉,直接继续处理就行了;相当于信任了所有的证书一样。

原因二

大多数页面都需要开启DOM缓存,如果未开启则也会出现空白页的情况

webSettings.setDomStorageEnabled(true);
原因三
  • 当访问页面(https://p.pinduoduo.com/cnH9JxxZ)时,被重定向到以pinduoduo://开头的一个链接上,仔细观察图中url可以发现这是一个自定协议的url,究其原因,就是拦截webview中的url, 如果url是自定义协议(如: tel, weixin, alipays 等等)开头的, 就url转换成原生调用(intent跳转), 因为webview只能识别http, https这样的协议. webview其实就相当于pc端的浏览器, 遇到http/https开头的url时会向host发起一个请求, 而遇到自定义的协议时就不知道该如何处理了, 因此就会出现ERR_UNKNOWN_URL_SCHEME这样的错误。
  • 解决方法:给WebView设置WebViewClient,并重写WebViewClient中的shouldOverrideUrlLoading方法
	@Override
    public boolean shouldOverrideUrlLoading(WebView wv, String url) {
        if(url == null) return false;

        try {
            if(url.startsWith("weixin://") //微信
                    || url.startsWith("alipays://") //支付宝
                    || url.startsWith("mailto://") //邮件
                    || url.startsWith("tel://")//电话
                    || url.startsWith("dianping://")//大众点评
                    || url.startsWith("tbopen://")//淘宝
                    || url.startsWith("openapp.jdmobile://")//淘宝
                    || url.startsWith("tmast://")//淘宝
                    || url.startsWith("pinduoduo://")//拼多多
                //其他自定义的scheme
            ) {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return true;
            }
        } catch (Exception e) { //防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
            return true;//没有安装该app时,返回true,表示拦截自定义链接,但不跳转,避免弹出上面的错误页面
        }

        //处理http和https开头的url
        wv.loadUrl(url);
        return true;
    }

代码

布局文件就包含一个简单的webview控件,过于简单就不再粘贴xml布局文件了

public class H5Activity extends AppCompatActivity {

    @BindView(R.id.h5_web_view)
    WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_h5);
        ButterKnife.bind(this);

        initData();
    }

    private void initData() {
        WebSettings webSettings = mWebView.getSettings();
        //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
        webSettings.setJavaScriptEnabled(true);
        // 若加载的 html 里有JS 在执行动画等操作,会造成资源浪费(CPU、电量)
        // 在 onStop 和 onResume 里分别把 setJavaScriptEnabled() 给设置成 false 和 true 即可

        //设置自适应屏幕,两者合用
        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

        //缩放操作
        webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

        //其他细节操作
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
        webSettings.setAllowFileAccess(true); //设置可以访问文件
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式

        webSettings.setDomStorageEnabled(true);

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView wv, String url) {
                if(url == null) return false;

                try {
                    if(url.startsWith("weixin://") //微信
                            || url.startsWith("alipays://") //支付宝
                            || url.startsWith("mailto://") //邮件
                            || url.startsWith("tel://")//电话
                            || url.startsWith("dianping://")//大众点评
                            || url.startsWith("tbopen://")//淘宝
                            || url.startsWith("openapp.jdmobile://")//淘宝
                            || url.startsWith("tmast://")//淘宝
                            || url.startsWith("pinduoduo://")//拼多多
                        //其他自定义的scheme
                    ) {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                        return true;
                    }
                } catch (Exception e) { //防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
                    return true;//没有安装该app时,返回true,表示拦截自定义链接,但不跳转,避免弹出上面的错误页面
                }

                //处理http和https开头的url
                wv.loadUrl(url);
                return true;
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                handler.proceed();
            }

        });

        mWebView.loadUrl("https://p.pinduoduo.com/cnH9JxxZ");
    }
}

如有问题,欢迎同学们在下方评论留言。

end 参考文章
简书 Doikki WebView出现net::ERR_UNKNOWN_URL_SCHEME错误

github Michael Lee 【Android】WebView加载HTTPS页面以及正确加载淘宝客连接

你可能感兴趣的:(Android基础,控件使用,android,webview,移动开发)