I want to use Picasso to load image in webview. I found the code below. The code is work properly but if the html have many images, which will lead the UI no response a little time.
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);
}
}
});
I found the following code will lead the UI no response.
Picasso.get()
and
Bitmap.compress()
For solve UI no response problem when Picasso.get()
call in WebViewClient.shouldInterceptRequest()
, I use Picasso.into()
to avoid thread block, but the method can’t call in WebViewClient.shouldInterceptRequest()
, that will throw exception “java.lang.IllegalStateException: Method call should happen from the main thread.”
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();
}
}
}
});
Because of Bitmap.compress
method will waste many resource, so I use another way to convert bitmap. I use the following code to convert Bitmap
to InputStream
. But use this way will lead the WebView can’t show images properly, images converted by ByteBuffer will display as error image.
int byteSize = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(byteSize);
bitmap.copyPixelsToBuffer(byteBuffer);
byte[] byteArray = byteBuffer.array();
ByteArrayInputStream bs = new ByteArrayInputStream(byteArray);
How to solve the problem? Thank you in advance.