在WebViewClient.shouldInterceptRequest中工作将导致UI没有响应一点时间

时间:2018-04-06 10:00:30

标签: android multithreading android-webview picasso freeze

我想用Picasso在webview中加载图片。我找到了下面的代码。代码工作正常,但如果html有很多图像,这将导致UI没有响应一点时间。

webView.setWebViewClient(new WebViewClient() {
    @SuppressWarnings("deprecation")
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        final String mime = URLConnection.guessContentTypeFromName(url);
        if (mime == null || !mime.startsWith("image")) {
            return super.shouldInterceptRequest(view, url);
        }
        try {
            final Bitmap image = Picasso.with(context).load(url).get();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            if (mime.endsWith("jpeg")) {
                image.compress(Bitmap.CompressFormat.JPEG, 100, out);
            } else if (mime.endsWith("png")) {
                image.compress(Bitmap.CompressFormat.PNG, 100, out);
            } else {
                return super.shouldInterceptRequest(view, url);
            }
            InputStream in = new ByteArrayInputStream(out.toByteArray());
            return new WebResourceResponse(mime, "UTF-8", in);
        } catch (IOException e) {
            Log.e(TAG, "Unable to load image", e);
            return super.shouldInterceptRequest(view, url);
        }
    }
});

我发现以下代码会导致UI没有响应。

Picasso.get()

Bitmap.compress()

为了在Picasso.get() WebViewClient.shouldInterceptRequest()中调用时解决用户界面无响应问题,我使用Picasso.into()来避免线程阻塞,但该方法无法调用WebViewClient.shouldInterceptRequest(),将抛出异常“java.lang.IllegalStateException:方法调用应该从主线程发生。”

final PipedOutputStream out = new PipedOutputStream();
PipedInputStream is = new PipedInputStream(out);
NetworkUtils.getPicassoInstance(getContext())
        .load(urlStr)
        .into(new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                if (bitmap != null) {
                    try {
                        if (mime.endsWith("jpeg")) {
                            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
                        } else if (mime.endsWith("png")) {
                            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });

由于Bitmap.compress方法会浪费很多资源,所以我用另一种方法来转换位图。我使用以下代码将Bitmap转换为InputStream。但是使用这种方式会导致WebView无法正常显示图像,ByteBuffer转换的图像将显示为错误图像。

int byteSize = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(byteSize);
bitmap.copyPixelsToBuffer(byteBuffer);  
byte[] byteArray = byteBuffer.array();
ByteArrayInputStream bs = new ByteArrayInputStream(byteArray);

如何解决问题? 提前谢谢。

0 个答案:

没有答案