【解决】trying to draw too large(147456000bytes) bitmap
异常信息
FATAL EXCEPTION: main
Process: com.sdt.sdtas, PID: 8695
java.lang.RuntimeException: Canvas: trying to draw too large(147456000bytes) bitmap.
at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:266)
at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:549)
at android.view.View.getDrawableRenderNode(View.java:23008)
at android.view.View.drawBackground(View.java:22937)
at android.view.View.draw(View.java:22711)
at android.view.View.updateDisplayListIfDirty(View.java:21594)
at android.view.View.draw(View.java:22450)
at android.view.ViewGroup.drawChild(ViewGroup.java:4528)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4289)
at android.view.View.updateDisplayListIfDirty(View.java:21585)
at android.view.View.draw(View.java:22450)
at android.view.ViewGroup.drawChild(ViewGroup.java:4528)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4289)
at android.view.View.updateDisplayListIfDirty(View.java:21585)
at android.view.View.draw(View.java:22450)
at android.view.ViewGroup.drawChild(ViewGroup.java:4528)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4289)
at android.view.View.draw(View.java:22722)
at com.android.internal.policy.DecorView.draw(DecorView.java:837)
at android.view.View.updateDisplayListIfDirty(View.java:21594)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:534)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:540)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:616)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:4530)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4250)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3373)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2178)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8808)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037)
at android.view.Choreographer.doCallbacks(Choreographer.java:845)
at android.view.Choreographer.doFrame(Choreographer.java:780)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
异常原因
以Bitmap默认采用的色彩模式Bitmap.Config.ARGB_8888为例;在该模式中一共有四个通道,其中A表示Alpha,R表示Red,G表示Green,B表示Blue;并且这四个通道每个各占8位即一个字节,所以合起来共计4个字节。
即 bitmap占用内存 = width x height x 4
查看源码可知安卓系统默认对图片的大小限制是100M
android/graphics/BaseRecordingCanvas.java
public static final int MAX_BITMAP_SIZE = getPanelFrameSize();private static int getPanelFrameSize() {final int DefaultSize = 100 * 1024 * 1024; // 100 MB;return Math.max(SystemProperties.getInt("ro.hwui.max_texture_allocation_size", DefaultSize),DefaultSize);
}@Override
protected void throwIfCannotDraw(Bitmap bitmap) {super.throwIfCannotDraw(bitmap);int bitmapSize = bitmap.getByteCount();if (bitmapSize > MAX_BITMAP_SIZE) {throw new RuntimeException("Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");}
}
解决方法
- 直接将工程中的大图,参考上述计算方式进行适当缩小。
- 如果发现工程中没有特别大的图片,可能是因为资源图放到了低分辨率的drawable中如drawable-mdpi,可以尝试将大图放到xxhdpi或者nodpi中。