2013-02-21 11 views
5

To nie jest duplikatem Mysterious stacktrace in Android developer console (bitmap size exceeds 32bits)Android: wielkość bitmapy przekracza 32 bit w DialogFragment

to pytanie nie stanowią jednej linii kodu i nie ma odpowiedzi albo; ponadto dostaję ten błąd, nawet jeśli ustawię rozmiar bitmapy na 32x32, jest to jedyna bitmapa, więc nie jest związana z pamięcią.

Co chcę zrobić

  1. Get rozmiaru ImageView,
  2. stworzyć bitmapę
  3. i narysować coś na płótnie.

Log.e wyjście do wielkości ImageView i dlatego Bitmap jest:

Width: 272 
Height: 136 

Co dzieje

Poniższy kod działa dobrze na Nexus4, Nexus7 i Desire HD (CM10) , ale uruchomienie aplikacji na emulatorze daje mi błąd pokazany poniżej (API 8).

Ustalenia

  1. Próbowałem go z pół rozmiaru i 32x32, co daje ten sam błąd.

  2. Wyświetlam ImageView w DialogFragment (ActionBarSherlock/HoloEveryWhere dla API 8), może to winowajca?

ImageView:

<ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="match_parent" 
     android:layout_height="1dp" 
     android:layout_marginBottom="12dp" 
     android:layout_marginTop="12dp" /> 

W mojej działalności:

iv = (ImageView) view.findViewById(R.id.imageView1); 
ViewTreeObserver vto = iv.getViewTreeObserver(); 
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
    @Override 
    public boolean onPreDraw() { 
     if (!waveFormMeasured) { 
      if (iv.getMeasuredWidth() > 1) { 
       width = iv.getMeasuredWidth(); 
       Log.e(TAG, "Width: " + width + " Height: " + width/2); 
       waveBitmap = Bitmap.createBitmap((int) width, (int) ((int) width/2), Config.RGB_565); 
       Log.e(TAG, "Bitmap created"); 
       waveCanvas = new Canvas(waveBitmap); 
       Log.e(TAG, "Bitmap set to Canvas"); 
       iv.getLayoutParams().height = width/2; 
       Log.e(TAG, "ImageView Height changed"); 
       iv.setImageBitmap(waveBitmap); 
       Log.e(TAG, "Bitmap set to ImageView"); 
       drawWaveForm(true); 
       Log.e(TAG, "WaveForm drawn"); 
       waveFormMeasured = true; 
       } 
      } 
    return true; 
    } 
    }); 

Co tu jest nie tak?

02-21 17:12:48.301: E/Drummers(375): Width: 272 Height: 136 
02-21 17:12:48.301: E/Drummers(375): Bitmap created 
02-21 17:12:48.301: E/Drummers(375): Bitmap set to Canvas 
02-21 17:12:48.301: E/Drummers(375): ImageView Height changed 
02-21 17:12:48.301: E/Drummers(375): Bitmap set to ImageView 
02-21 17:12:48.623: E/Drummers(375): WaveForm drawn 
02-21 17:12:48.842: E/AndroidRuntime(375): FATAL EXCEPTION: main 
02-21 17:12:48.842: E/AndroidRuntime(375): java.lang.IllegalArgumentException: bitmap size exceeds 32bits 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.graphics.Bitmap.nativeCreate(Native Method) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.graphics.Bitmap.createBitmap(Bitmap.java:477) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.View.buildDrawingCache(View.java:6577) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.onAnimationStart(ViewGroup.java:1259) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.drawChild(ViewGroup.java:1505) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.View.draw(View.java:6883) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.View.draw(View.java:6986) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.widget.ScrollView.draw(ScrollView.java:1409) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.View.buildDrawingCache(View.java:6640) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.onAnimationStart(ViewGroup.java:1259) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.drawChild(ViewGroup.java:1505) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.View.draw(View.java:6883) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
02-21 17:12:48.842: E/AndroidRuntime(375): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewRoot.draw(ViewRoot.java:1522) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewRoot.performTraversals(ViewRoot.java:1258) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.os.Handler.dispatchMessage(Handler.java:99) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.os.Looper.loop(Looper.java:123) 
02-21 17:12:48.842: E/AndroidRuntime(375): at android.app.ActivityThread.main(ActivityThread.java:3683) 
02-21 17:12:48.842: E/AndroidRuntime(375): at java.lang.reflect.Method.invokeNative(Native Method) 
02-21 17:12:48.842: E/AndroidRuntime(375): at java.lang.reflect.Method.invoke(Method.java:507) 
02-21 17:12:48.842: E/AndroidRuntime(375): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
02-21 17:12:48.842: E/AndroidRuntime(375): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
02-21 17:12:48.842: E/AndroidRuntime(375): at dalvik.system.NativeStart.main(Native Method) 
+0

Czy znalazłeś rozwiązania, a nawet przyczynę tego wyjątku? –

+0

ślad stosu sugeruje, że awaria nie znajduje się na 'waveBitmap', ale jest spowodowana przez animację, która rozpoczyna wywoływanie' buildDrawingCache() '. –

Odpowiedz

2

bitmapy mają limit rozmiaru, który zależy od urządzenia. Rozmiar jest zwykle wielkości samego ekranu. Istnieje kilka pytań dotyczących przepełnienia stosu, które rozwiązują ten problem, takich jak OutOfMemoryError: bitmap size exceeds VM budget :- Android lub Strange out of memory issue while loading an image to a Bitmap object. Jeśli potrzebujesz bardzo dużego obrazu, możesz po prostu podzielić go na mniejsze rozmiary i umieścić je w wielu numerach ImageViews. Kilka miesięcy temu stworzyłem aplikację z dużym, przewijalnym obrazem, który składał się z około 15 obrazów połączonych ze sobą bezproblemowo - potwierdzenie, że jest to dobry sposób na przejście.

W ostatecznej notatce mapy bitowe są trudne do bezpośredniego działania, ze względu na problemy z pamięcią, które powodują w systemie Android. Zajrzyj do BitmapFactory.Options i zawsze pamiętaj, aby anulować i anulować nieużywane bitmapy.

Edit

To może mieć również coś wspólnego z modyfikując zawartość widoku w onPreDraw().Ten post: When Can I First Measure a View? omawia, w jaki sposób edycja rozmiaru widoku w tej metodzie spowoduje, że onPreDraw() będzie ciągle wywoływany, podczas gdy wykonywanie tych operacji za pomocą onGlobalLayoutListener da oczekiwane wyniki.

+0

Jestem tego świadomy, ale rozmiar to tylko 272x136 (jak wspomniano w moim poście), który jest mniejszy niż szerokość ekranu, ponieważ jest to obraz wyświetlany w DialogFragment. Nie dostaję błędu braku pamięci, ale wspomnianego powyżej w pytaniu. – stefple

+0

Ten sam błąd w rozmiarze bitmapy ustawionym na 32x32. To jest jedyna bitmapa, którą pokazuję, nic więcej z ogromną potrzebą pamięci w mojej aplikacji. – stefple

+0

@stefple Zobacz moją zmianę – Phil

0

Wygląda na to, że wystąpił problem z ustawieniem DialogFragment na match_parent (zarówno szerokość, jak i wysokość) w API 8. Nie mogę dokładnie powiedzieć, co się dzieje, ale dodanie do tego poniższego szablonu (ja miałem parę z LinearLayouts/TextView/SeekBars itp z layout_width = "match_parent" i całość pracowała w API 11+):

<org.holoeverywhere.widget.ListView 
    android:id="@+id/sampleList" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 
</org.holoeverywhere.widget.ListView> 

następujące nie działa, aby ustawić go w trybie pełnoekranowym:

setStyle(...) 

lub

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);