5

This is not a duplicate of Mysterious stacktrace in Android developer console (bitmap size exceeds 32bits)

That question didn't provide a single line of code and there's no answer either; besides, I get this error even if I set the Bitmap size to 32x32, it is the only Bitmap, so it is not memory related.

What I want to do

  1. Get the size of an ImageView,
  2. create a BitMap
  3. and draw something on a Canvas.

The Log.e output for the size of the ImageView and therefore Bitmap is:

Width: 272
Height: 136

What happens

The below code works well on Nexus4, Nexus7 and Desire HD (CM10), but running the app on the emulator gives me the error shown below (API 8).

Findings

  1. I've tried it with half the size and 32x32, which gives the same error.

  2. I am displaying the ImageView in a DialogFragment (ActionBarSherlock/HoloEveryWhere for API 8), maybe that's the culprit?

ImageView:

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

In my activity:

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

What is wrong here ?

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)
4

2 回答 2

2

位图的大小限制取决于设备。大小一般是屏幕本身的大小。有几个关于堆栈溢出的问题可以解决这个问题,例如OutOfMemoryError: bitmap size超出 VM budget :- AndroidStrange out of memory issue while loading an Image to a Bitmap object。如果您需要一个非常大的图像,您可以简单地将其分解为更易于管理的尺寸,并将它们放在多个ImageViews. 几个月前,我创建了一个应用程序,其中包含一个可滚动的大型图像,其中大约 15 个图像无缝地串在一起 - 验证这是一个很好的方法。

最后一点,位图很难直接使用,因为它们会在 Android 上引起内存问题。查看BitmapFactory.Options,并始终记住取消和recycle未使用的位图。

编辑

它也可能与修改 View in 的内容有关onPreDraw()。这篇文章:我什么时候可以第一次测量视图?讨论了如何在此方法中编辑 View 的大小将导致onPreDraw()不断调用,而使用 an 执行这些操作onGlobalLayoutListener将给出预期的结果。

于 2013-02-21T17:30:09.967 回答
0

在 API 8 中将 DialogFragment 设置为 match_parent(宽度和高度)似乎存在问题。我不能确切地说发生了什么,但添加以下虚拟布局修复了它(我有几个 LinearLayouts/TextViews/带有 layout_width="match_parent" 的 SeekBars 等,整个事情在 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);
于 2013-02-23T16:25:25.740 回答