Android:DialogFragment中的位图大小超过32位

时间:2013-02-21 17:18:12

标签: android bitmap imageview

这不是Mysterious stacktrace in Android developer console (bitmap size exceeds 32bits)

的副本

这个问题没有提供单行代码,也没有答案;此外,即使我将位图大小设置为32x32,我也会收到此错误,它是唯一的Bitmap,因此它与内存无关。

我想做什么

  1. 获取ImageView的大小,
  2. 创建一个BitMap
  3. 在画布上画一些东西。
  4. ImageView的大小Log.e输出,因此Bitmap是:

    Width: 272
    Height: 136
    

    会发生什么

    以下代码适用于Nexus4,Nexus7和Desire HD(CM10),但在模拟器上运行应用程序会出现以下错误(API 8)。

    首饰

    1. 我尝试了一半大小和32x32,这也给出了同样的错误。

    2. 我在DialogFragment中显示ImageView(针对API 8的ActionBarSherlock / HoloEveryWhere),也许这是罪魁祸首?

    3. ImageView的:

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

2 个答案:

答案 0 :(得分:2)

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

最后一点,由于Android导致的内存问题,位图难以直接使用。查看BitmapFactory.Options,并始终记住取消recycle未使用的位图。

修改

它可能与修改onPreDraw()中的视图内容有关。这篇文章:When Can I First Measure a View?讨论了如何在此方法中编辑视图的大小将导致onPreDraw()不断被调用,而使用onGlobalLayoutListener执行这些操作将会产生预期的结果。

答案 1 :(得分:0)

在API 8中将DialogFragment设置为match_parent(宽度和高度)似乎存在问题。 我不能确切地说出发生了什么,但添加了以下虚拟布局修复它(我有几个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);