2017-08-09 57 views
11

Mam niestandardowy WebView i chcę uzyskać bitmapę jego zawartości (poza ekranem). Kiedyś ten kod, który dostałem od here:Uzyskiwanie bitmapy z WebView generuje awarię OutOfMemory

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; 
} 

działa dobrze aż do momentu, kiedy powiększyć dużo, w takim przypadku mogę OutOfMemory wypadku. Testowałem to z tym samym obrazem (nieznacznie powiększony i powiększony do maksimum) i zachowuje się w ten sam sposób, o którym wspomniałem powyżej.

starałem się temu przeciwdziałać, dodając

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

na początku, ale to nie pomaga w ogóle.

+0

Szybkie obejście - można dodać androida: largeHeap = "true" w pliku manifestu więcej pamięci. –

+2

nieprzyjemne obejście, które nie będzie działało przez większość czasu ... po prostu opóźni twój wyjątek OOM – MarkySmarky

+0

dla mnie oczywiste jest, że chcesz uzyskać zbyt dużą bitmapę. Nie możesz uzyskać nieskończonej pamięci w swojej aplikacji. –

Odpowiedz

0

Okay, sam to załamałem. Problem tkwił w tym, że funkcja zwróciła próbkę Bitmap przed zakończeniem procedury pomniejszania, więc musiałem ją opóźnić.

że wprowadza

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

zmuszając zmienić strukturę zależności od public Bitmap do public void. Here's directly related thread. Pomimo kilku drobnych usprawnień nadal muszę naprawić, podejście działa jak czar

+0

Dlaczego więc nie otrzymasz bezpośrednio oryginalnych wymiarów 'WebView' przed powiększeniem i użyjesz' Bitmap.createScaledBitmap() ', używając oryginalnych wymiarów jako wymiarów docelowych dla' Bitmapy'? –

+0

@Oleksandr Firsov, jesteś pewien, że nie dostałeś żadnej pamięci za pomocą handler'a. –

+0

@Chestan Joshi Nope, testowałem to kilka razy z różnymi obrazami i bez błędów. –

-1

Quick Fix: -

Ustaw android: largeHeap = "true" w pliku AndroidManifest.xml.

<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 powodzenia :)

+0

Ta flaga jest często ignorowana, a nawet w przypadku dużej sterty nadal masz możliwość uzyskania OOM podczas tworzenia bitmapy. – Dimezis