当Android N Display Size设置为大于Small时,“画布:试图绘制太大的位图”


81

我有一个发布的应用程序,当新引入的Display sizeOS设置设置为太大的值时,在Android N上启动时崩溃。

当我查看logcat时,会看到以下消息:

java.lang.RuntimeException: Canvas: trying to draw too large(106,975,232 bytes) bitmap.

我已经在我的第一个Activity中将问题追溯到ImageView,该ImageView显示了一个不错的大背景图像。有问题的图像是2048x1066,位于我的通用drawables目录中,因此无论密度如何,都将使用该图像。

Display size设置为时,一切正常Small。但是当我转到时Default,它停止工作。然后,如果我将图像换成较小的图像,它将在处工作Default,但如果升至Large,它将再次停止工作。

我的猜测是,Display size向上调整会使您的设备像具有更高像素密度的物理上较小的设备那样工作。但是我不明白我应该在这里做什么。如果我以逐渐减小的分辨率输入逐渐减小的图像,则在大尺寸显示器上看起来效果不佳。还是我不明白某事?

任何指针将不胜感激。


23
“相关图片为2048x1066,位于我的通用drawables目录中,因此无论密度如何,都将使用该图片”-res/drawable/是的同义词res/drawable-mdpi/。如果您不想根据浓度缩放图像,请使用res/drawable-nodpi/res/drawable-anydpi/
CommonsWare,2016年

3
“你是说生活在各种不同资源目录中的一个100x100像素的图像实际上已缩放以创建虚拟的不同分辨率版本,然后再进行布局?” -这取决于您拥有的密度和运行的设备。如果存在完全匹配的内容,则不会重新采样。如果不完全匹配,则对附近密度的图像重新采样。因此,如果您只有res/drawable/foo.png(aka,res/drawable-mdpi/foo.png),而设备为xhdpi,则图像将沿两个轴加倍,占用内存4倍。
CommonsWare

4
错误中的106975232值恰好是图像分辨率的49倍,这意味着沿两个轴重新采样7倍。这比我预期的要高得多。我还没有机会
CommonsWare

6
49x不错!我想我可以解释为什么这么高。请记住,该数字是字节。该图像是24位的,但每个像素可能以32位读取。这将使它在内存中达到8736672字节,这恰好是该数字的12.25倍,这又意味着沿每个轴进行3.5倍缩放。该设备的速度为xxhdpi,因此似乎正确。无论哪种方式,我都不知道资源会像这样被重新采样。感谢您的帮助!(顺便说一句,将图像移动到drawable-nodpi确实可以修复它。)
Brian Rak

1
您确实应该接受约翰的回答
S. Jacob Powell,

Answers:


166

就我而言,将(高分辨率)启动位图从drawable移至drawable-xxhdpi是解决方案。

我有同样的问题。我并不怀疑我的启动屏幕是问题所在,因为启动应用程序时显示该屏幕,但事实证明启动屏幕是问题所在。

在我的情况下,初始屏幕具有xxhdpi分辨率,并且错误地将其放置在drawable文件夹中,而不是放在drawable-xxhdpi中。这使Android假定初始屏幕具有mdpi分辨率,并将图像缩放到所需大小的3 * 3倍,并尝试创建位图。


我猜:所以,android将图像从xxhdpi缩放到hdpi,例如成为更亮的图像?如您所说的从3 * 3-> 1/1到1/3?
Ninja Coding'7

如kalsara Magamage所述,现在是mipmap-xxhdpi。
丹娜·罗宾逊

35

在将以下代码添加到android:行之间的Manifest文件的application标签后,我解决了问题。

android:hardwareAccelerated="false"

3
好吧,花了几个小时后,此解决方案可解决小米和三星的移动问题。
Shihab Uddin

3
这将导致禁用CardView的所有高程。因此,正确的解决方案是将位图缩放为较小的尺寸。
萨钦索马

与其在“活动”,“窗口”,“视图”级别中控制它的“应用程序”级别中禁用硬件加速,不如使用它。
Mukhammadsher

但是,这样做之后还有其他一些问题android:hardwareAccelerated="false" 。示出在具有低于22的API级的一些设备的奇数视图
王子Dholakiya

请勿这样做,这会使您的应用程序变慢。
古玩

11

我不知道这对某些人有帮助,但是我将其留在这里。以我为例-问题仅出现在装有Android 7的Sumsung设备上,而问题出在初始屏幕比例上。将高度更改为1024像素后-一切正常


我的问题是可绘制(无后缀)文件夹中的位图(jpg,png)。这是我的愚蠢,但也许可以帮助某人:-)
gingo

这很有帮助!只有三星有同样的问题...您首先有什么?如何解决?
M'hamed '18 -4-9

您是否尝试从URL加载图像。我只在Android 7上使用Samsung Galaxy S6面临相同的问题。我正在RecyclerView中加载图像。我仍然不知道这一点。@ M'hamed
Rohit Singh



3

如果您使用Picasso将像这样更改为Glide。

删除毕加索

Picasso.get().load(Uri.parse("url")).into(imageView)

改变滑翔

Glide.with(context).load("url").into(imageView)

更高效


即使从毕加索切换到Glide,我仍然会收到错误消息。在三星J6手机上。和Moto Z2 :(
罗希特·辛格

1

在某些情况下,需要将原始位图绘制到ImageViews,照片编辑应用程序等中,

如上述设置

android:hardwareAccelerated="false"

会导致不良的UI体验,您可以设置hardwareAccelerated仅选择一个活动,以绘制高分辨率图像

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

1

我检查了Logcat

进程:co.coolresume,PID:11145 java.lang.RuntimeException:画布:试图绘制太大(572166144bytes)的位图。在android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)在android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97)在android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529)在android。 android.view.View.draw(View.java:19380)的widget.ImageView.onDraw(ImageView.java:1367)

我使用下一个清单解决了错误

 <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:hardwareAccelerated="false">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

0

图标文件太大,Android无法有效,平稳地加载。Android通过其智能算法认识到这一点。

您可以使用asystat使用Final Android Resizer调整图标文件的大小。将它们的大小调整为“ xhdpi”或更低。

将调整大小后的照片以可绘制方式放置或覆盖现有的大图标文件。

然后,您完成了。


0

如果您正在使用滑行功能,并且一次加载一千张图像或某些图像,则这是滑行问题或用于设置图像视图的任何操作。您只需在滑行中应用比例类型即可解决该问题。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.