本文介绍了Android:DialogFragment 中的位图大小超过 32 位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是 神秘的堆栈跟踪在Android 开发者控制台(位图大小超过 32 位)

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

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.

我想做什么

  1. 获取ImageView的大小,
  2. 创建位图
  3. 并在画布上画一些东西.

ImageView 和 Bitmap 大小的 Log.e 输出是:

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

Width: 272
Height: 136

发生了什么

以下代码在 Nexus4、Nexus7 和 Desire HD (CM10) 上运行良好,但在模拟器上运行该应用程序时出现如下所示的错误 (API 8).

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

发现

  1. 我用一半的尺寸和 32x32 尝试过,它给出了同样的错误.

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

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

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

图像视图:

<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: bitmap size超出 VM 预算:- Android将图像加载到位图对象时出现奇怪的内存不足问题 .如果您需要非常大的图像,您可以简单地将其分解为更易于管理的尺寸,并将它们放置在多个 ImageViews 中.几个月前,我创建了一个应用,其中包含一个可滚动的大图片,其中大约 15 张图片无缝地串在一起 - 验证这是一个不错的方法.

bitmaps have a size limit that depends on the device. The size is generally the size of the screen itself. There are several questions on stack overflow that address this issue, such as OutOfMemoryError: bitmap size exceeds VM budget :- Android or Strange out of memory issue while loading an image to a Bitmap object . If you need a very large image, you can simply break it down into more manageable sizes, and place them in multiple ImageViews. I created an app several months ago with a large, scrollable image that was about 15 images strung together seamlessly - validation that this is a good way to go.

最后一点,位图很难直接使用,因为它们在 Android 上会导致内存问题.查看 BitmapFactory.Options,并始终记得取消和回收未使用的位图.

On a final note, bitmaps are difficult to work with directly, due to the memory issues they cause on Android. Look into BitmapFactory.Options, and always remember to nullify and recycle unused bitmaps.

编辑

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

It may also have something to do with modifying the contents of the View in onPreDraw(). This post: When Can I First Measure a View? discusses how editing the size of a View in this method will cause onPreDraw() to continually be called, whereas performing these operations with an onGlobalLayoutListener will give the expected results.

这篇关于Android:DialogFragment 中的位图大小超过 32 位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 09:49