我想用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);
如何解决问题? 提前谢谢。