Android: размер растрового изображения превышает 32 бит в DialogFragment

Это не дубликат Mysterious stacktrace в консоли разработчика Android (размер растрового изображения превышает 32 бит)

Этот вопрос не содержит ни одной строки кода, и ответа нет; Кроме того, я получаю эту ошибку, даже если я установил размер растрового изображения в 32×32, это единственный битмап, поэтому он не связан с памятью.

Что я хочу сделать

  1. Получите размер ImageView,
  2. Создать BitMap
  3. И нарисуйте что-нибудь на холсте.

Выход Log.e для размера ImageView и, следовательно, Bitmap:

 Width: 272 Height: 136 

Что происходит

Нижеприведенный код хорошо работает на Nexus4, Nexus7 и Desire HD (CM10), но запуск приложения на эмуляторе дает мне ошибку, показанную ниже (API 8).

Выводы

  1. Я пробовал его с половиной размера и 32×32, что дает ту же ошибку.

  2. Я показываю ImageView в DialogFragment (ActionBarSherlock / HoloEveryWhere для API 8), может быть, это преступник?

ImageView:

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

В моей деятельности:

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

Что здесь не так?

 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) 

Растровые изображения имеют ограничение по размеру, которое зависит от устройства. Размер обычно составляет размер самого экрана. Есть несколько вопросов о переполнении стека, которые устраняют эту проблему, например OutOfMemoryError: размер растрового изображения превышает бюджет VM: – проблема с Android или Strange из памяти при загрузке изображения в объект Bitmap . Если вам нужно очень большое изображение, вы можете просто разбить его на более управляемые размеры и разместить их в нескольких ImageViews . Несколько месяцев назад я создал приложение с большим прокручиваемым изображением, в котором было собрано около 15 изображений, – это проверка, что это хороший способ.

В конечном итоге растровые изображения трудно работать напрямую, из-за проблем с памятью, которые они вызывают на Android. Посмотрите на BitmapFactory.Options и всегда помните об аннулировании и recycle неиспользуемых растровых изображений.

редактировать

Он также может иметь какое-то отношение к изменению содержимого View в onPreDraw() . Это сообщение: Когда я могу сначала измерить вид? Обсуждается, как редактирование размера представления в этом методе будет постоянно вызывать onPreDraw() , тогда как выполнение этих операций с помощью onGlobalLayoutListener даст ожидаемые результаты.

Кажется, что проблема связана с настройкой DialogFragment для match_parent (как ширины, так и высоты) в API 8. Я не могу точно сказать, что происходит, но добавив следующий фиктивный макет, исправил его (у меня было несколько LinearLayouts / TextViews / SeekBars и т. Д. С layout_width = "match_parent", и все это работало в API 11+):

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

Не удалось настроить его на полноэкранный режим:

 setStyle(...) 

или

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