Android8.0以上WebView获取img控件图片链接失败

Posted by Don on August 1, 2019

前言

Android Webview中点击图片预览大图的一般做法是在onPageFinished(WebView view, String url)方法中调用doucument.getElementsByTagName(“img”), 然后遍历元素拿到src的图片地址;但是最近的一个项目在android8.0以上的系统中有一定的几率获取到的src为空,导致无法预览大图。

原因

WebViewClient.onPageFinished()这个方法的行为很诡异,有时webview在load完页面后调用onPageFinished,但是有时webview内容未加载完时就调用了。
PS:由于以上原因,因此不建议在此方法中添加webview load完毕时需要调用的回调

解决方案

给webview添加PictureListener监听,以此来替代onPageFinished()方法,该监听会在webview实际更新内容时被触发;
但是此监听已被弃用,使用此方法需要承担一定的风险。
PS:看到有人网上说可以在onProgressChanged(WebView view,int newProgress)方法中当newProgress=100时获取图片链接,但是此方法也并非可靠。

预览大图完整源码:

webview设置监听

//设置图片点击监听
mWebView.addJavascriptInterface(new MJavascriptInterface(this),"imagelistener");

private class MJavascriptInterface {
        private Context context;

        MJavascriptInterface(Context context) {
            this.context = context;
        }

        //点击图片回调方法
        // 必须添加注解,否则无法响应
        @JavascriptInterface
        public void openImage(String currentImg,String[] imgArray) {
            //查看大图的activity,需自己编写
            Intent intent = new Intent(context, BigPictureActivity.class);
            intent.putExtra("image", currentImg);
            intent.putExtra("imageUrls", imgArray);
            context.startActivity(intent);
        }
    }

在PictureListener中注入js

mWebView.setPictureListener(new WebView.PictureListener() {
            @Override
            public void onNewPicture(WebView webView, Picture picture) {
                 //待网页加载完全后设置图片点击的监听方法
                 addImageClickListener(webView);
            }
        });
        
private void addImageClickListener(WebView view) {
        // 用"javascript:(%s)()"包住
        String js = "javascript:(function(){" +
                "var objs = document.getElementsByTagName(\"img\"); " +
                " var array=new Array(); " +
                "for(var i=0;i<objs.length;i++)  " +
                "{" +
                "array[i]=objs[i].src;" +
                "    objs[i].onclick=function()  " +
                "   {  " +
                "        window.imagelistener.openImage(this.src,array);  " +
                "    }  " +
                "}" +
                "})()";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            evaluateJavascript(js, null);//比loadUrl(js)高效
        } else {
            loadUrl(js);
        }
    }