Friday, August 18, 2017

Getting Bitmap from WebView generates OutOfMemory crash

Leave a Comment

I have a custom WebView and I want to get a bitmap of its content (offscreen included). I used this code, which I got from here:

 public static Bitmap getBitmapFromWebviewV2(WebView webView) {     webView.measure(View.MeasureSpec.makeMeasureSpec(         View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),         View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));     webView.layout(0, 0, webView.getMeasuredWidth(),             webView.getMeasuredHeight());     webView.setDrawingCacheEnabled(true);     webView.buildDrawingCache();     Bitmap bm = Bitmap.createBitmap(webView.getMeasuredWidth(),             webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);      Canvas bigcanvas = new Canvas(bm);     Paint paint = new Paint();     int iHeight = bm.getHeight();     bigcanvas.drawBitmap(bm, 0, iHeight, paint);     webView.draw(bigcanvas);     return bm; } 

It works fine up to the point when I zoom in a lot, in which case I get OutOfMemory Crash. I tested this with the same picture (slightly zoomed and zoomed to the max) and it behaves in the same way I mentioned above.

I tried to counter this by adding

while(webView.canZoomOut()){       webView.zoomOut(); } 

at the start, but it doesn't help at all.

3 Answers

Answers 1

Okay, I've cracked this one meself. The problem indeed was in the fact that the function returned the Bitmap waay before the zooming out procedure was over, so I had to delay it.

I incorporated

Handler handler = new Handler();         handler.postDelayed(new Runnable() {             @Override             public void run() {                 //bulk of my code             }         }, 1000); 

which forced to change the structure of the function from public Bitmap to public void. Here's directly related thread. Despite some minor tweaks I still need to fix, the approach works like a charm

Answers 2

Quick fix:-

Set android:largeHeap="true" in your AndroidManifest.xml file.

<application     android:name="yourapplication"     android:allowBackup="true"     android:icon="@mipmap/ic_launcher_rounded"     android:label="@string/app_name"     android:largeHeap="true"     android:roundIcon="@mipmap/ic_launcher_rounded"     android:supportsRtl="true"     android:theme="@style/AppTheme"> 

Gud luck :)

Answers 3

You write code to capture Bitmap from Webview but code which creates outOfmemmory you should write onces.

webView.measure(View.MeasureSpec.makeMeasureSpec(             View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));  Bitmap bm = Bitmap.createBitmap(webView.getMeasuredWidth(),                 webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); 

So above code should be written once and create Bitmap object Global and check if it's not null then over right new drawing cache in Bitmap.

Because each time when you create new Bitmap it consumes a lot of memory.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment