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.