相关文章推荐
不要命的汉堡包  ·  WebView全面解析 ·  2 月前    · 
拉风的勺子  ·  WebView - .NET MAUI | ...·  1 周前    · 
一身肌肉的打火机  ·  QT最佳实践 - 简书·  1 年前    · 
狂野的鼠标垫  ·  android - After ...·  1 年前    · 
呐喊的生姜  ·  SQL ...·  1 年前    · 

WebView 的 shouldInterceptRequest 可以让我们监听WebView发出的请求并做相应的处理,但有个严重的问题:浏览器的渲染以及资源加载都是在一个线程中,如果在shouldInterceptRequest 处理时间过长,WebView界面就会阻塞,这是非常非常不好的。

本人最近遇到个问题,用WebView做显示,里面有个别特定url的图片需要做特殊的加载处理。所以就在shouldInterceptRequest 判断url,然后用java加载,处理,最后返回给 WebView。

一开始用 shouldInterceptRequest做了如下处理:

@Override
            public WebResourceResponse shouldInterceptRequest(WebView view,  String url) {
                Log.i(TAG, "shouldInterceptRequest url=" + url + ";threadInfo" + Thread.currentThread());
                WebResourceResponse response = null;
                if(url.contains("avatar.php?")){
                    Bitmap bitmap = ImageLoader.getInstance().loadImageSync(url);
                    if (bitmap != null) {
                        InputStream in = IOUtils.bitmap2InputStream(bitmap, 100);
                        response = new WebResourceResponse("image/png", "UTF-8", in);
                return response;


    开始感觉没有什么大问题,一段时间后发现在网络环境差的情况下非常慢,要好半天加载动画才会消失(WebView加载完成时取消加载动画的),经调试发现所有 shouldInterceptRequest的执行都在同一个线程内,如果此方法内处理时间长,不能及时返回结果,就会造成界面长时间无响应的情况, 真是万万没想到。。。

改成异步加载即可:

@Override
public WebResourceResponse shouldInterceptRequest(WebView view,  String url) {
    Log.i(TAG, "shouldInterceptRequest url=" + url + ";threadInfo" + Thread.currentThread());
    WebResourceResponse response = null;
    if(url.contains("avatar.php?")){
        try {
            final PipedOutputStream out = new PipedOutputStream();
            PipedInputStream in = new PipedInputStream(out);
            ImageLoader.getInstance().loadImage(url, new ImageLoadingListener() {
                @Override
                public void onLoadingStarted(String s, View view) {}
                @Override
                public void onLoadingFailed(String s, View view, FailReason failReason) {}
                @Override
                public void onLoadingCancelled(String s, View view) {}
                @Override
                public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                    if (bitmap != null) {
                        try {
                            out.write(IOUtils.Bitmap2Bytes(bitmap));
                            out.close();
                        }catch (Exception e){
                            e.printStackTrace();
            response = new WebResourceResponse("image/png", "UTF-8", in);
        }catch (Exception e){
            e.printStackTrace();
    return response;