启动 Xamarin.forms 应用程序时出错:尝试绘制太大(165514752 字节)位图

Posted

技术标签:

【中文标题】启动 Xamarin.forms 应用程序时出错:尝试绘制太大(165514752 字节)位图【英文标题】:Error starting Xamarin.forms application: trying to draw too large(165514752bytes) bitmap 【发布时间】:2021-10-01 06:17:50 【问题描述】:

当我在安装后第一次运行 Xamarin.forms android 应用程序时,它会打开一个页面,其中包含大小为 89.2 KB 的 Avertissement _5.png 图像。

<Grid HorizontalOptions="StartAndExpand" VerticalOptions="StartAndExpand">
                <Image x:Name="Advert" 
                       Opacity="0.7" 
                       IsVisible="false" 
                       Aspect="Fill"
                       Source="Avertissement_5.png"/>
                    <Label x:Name="AdvertText1"
                       IsVisible="false"
                       FontSize="Medium"
                       TextColor="White"
                       FontAttributes="Italic"
                       Text="Vous n'avez aucune liste !"
                       VerticalOptions="Center"
                       HorizontalOptions="Center"
                       Margin=" 0,-30,0,0"/>
                    <Label x:Name="AdvertText2"
                       IsVisible="false"
                       FontSize="Medium"
                       TextColor="White"
                       FontAttributes="Italic"
                       Text="Tapez sur le bouton + pour en ajouter une..."
                       VerticalOptions="Center"
                       HorizontalOptions="Center"
                       Margin=" 0,30,0,0"/>
            </Grid>

此图像放置在 Resources / drawable 文件夹中。 在某些手机(主要是三星品牌)上,查看此页面时应用程序崩溃并出现以下错误:

致命异常:主要 进程:com.ApriSoft.memocourses,PID:5826 java.lang.RuntimeException: Canvas: 试图绘制太大(165514752bytes) 位图。 在 android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229) 在 android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97) 在 android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529) 在 android.widget.ImageView.onDraw(ImageView.java:1367) 在 android.view.View.draw(View.java:20338) 在 android.view.View.updateDisplayListIfDirty(View.java:19283) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.draw(View.java:20341) 在 android.view.View.updateDisplayListIfDirty(View.java:19283) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:1426) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.draw(View.java:20341) 在 android.view.View.updateDisplayListIfDirty(View.java:19283) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.updateDisplayListIfDirty(View.java:19274) 在 android.view.View.draw(View.java:20061) 在 android.view.ViewGroup.drawChild(ViewGroup.java:4421) 在 android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) 在 android.view.View.draw(View.java:20341) 在 com.android.internal.policy.DecorView.draw(DecorView.java:979) 在 android.view.View.updateDisplayListIfDirty(View.java:19283) 在 android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686) 在 android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692) 在 android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800) 在 android.view.ViewRootImpl.draw(ViewRootImpl.java:3447) 在 android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3234) 在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2769) 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1738) 在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7745) 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:911) 在 android.view.Choreographer.doCallbacks(Choreographer.java:723) 在 android.view.Choreographer.doFrame(Choreographer.java:658) 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897) 在 android.os.Handler.handleCallback(Handler.java:789) 在 android.os.Handler.dispatchMessage(Handler.java:98) 在 android.os.Looper.loop(Looper.java:164) 在 android.app.ActivityThread.main(ActivityThread.java:6938) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

当我的 Resources / drawable 文件夹中没有任何位图文件时,我不明白这个关于 165514752 字节的位图文件大小的错误,并且这个错误只发生在某些手机上。非常感谢您的帮助,因为我的应用无法在某些手机上使用。

【问题讨论】:

“位图”是图像文件在内存中的样子。如果手机每个像素使用 4 个字节,那么这就是一张包含 165514752/4 = 大约 4000 万像素的图像。那将是大约 6000 像素 x 7000 像素。您的 png 文件的尺寸(以像素为单位)是多少?如果图像确实有那么多像素,请使用 Photoshop 或其他软件将其缩小,使其像素更少。 (磁盘上文件的大小无关紧要。) 我的 png 文件大小为 92 KB。我不知道如何计算这个文件的大小(以像素为单位)。但最重要的问题是:为什么除了少数手机之外,这张图片在大多数手机上都能正确显示? 您可以尝试将其移至drawable-xxhdpi 文件夹。 @Leo :当我将 png 文件移动到 mipmap-xxhdpi 文件夹时,它不显示。我们是否应该根据这个修改来修改xaml代码?感谢您的回复。 @ToolmakerSteve:我的文件大小(以像素为单位)为 1842 * 2496 = 4597632 像素。我忘了说,当页面加载时,我会显示另一个图像(大小相同),但它被第一个隐藏了。总共有 9,195,264:我们离 4000 万还差得很远…… 【参考方案1】:

165514752 字节 / 4597632 像素 = 每像素 36 字节。

三星手机必须有屏幕(像素)Density=3;它将图像扩展 3 倍,这需要 3 x 3 x 4 字节/像素 = 36 字节/像素。

幸运的是,有一个解决方法:在Resources 中创建一个drawable-nodpi 文件夹。将图像移到那里。

正如in this SO post解释的那样:

drawable-nodpi 将绕过缩放,drawable 将使用默认缩放

请务必从文件夹 drawable 中删除原始图像。这迫使它查看“替代”可绘制文件夹。


这应该有助于任何对图像进行预缩放(以匹配屏幕密度)的 Android 手机上的图像加载性能。

【讨论】:

在进行了您告诉我的更改(在资源中创建一个“drawable-nodpi”文件夹并移动 png 文件)之后,一切似乎都工作正常:我不再有错误在 pre- Google Play 控制台的启动报告。我已经找了几个星期的解决方案,你给了我。非常感谢您的帮助!

以上是关于启动 Xamarin.forms 应用程序时出错:尝试绘制太大(165514752 字节)位图的主要内容,如果未能解决你的问题,请参考以下文章

构建不成功:Xamarin.Forms 中的 Android 项目出错

Xamarin Forms Ui 项目(多平台)

应用程序启动与否时发出通知铃声(Xamarin.Forms)

Xamarin.Forms 中的 Droid 自定义选取器渲染器出错

启动 Xamarin Forms Android 应用程序时未找到 RealmObject

使用Xamarin.Forms应用程序填充iPhone X屏幕