VectorDrawable Resources$NotFoundException 而 xml 矢量可绘制资源文件确实存在
VectorDrawable Resources$NotFoundException while xml vector drawable resource file does exist
我的应用最小 SDK 是 21,所以不需要添加
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
应用程序 class 因为它只适用于低于 21(无论如何我尝试添加它但没有结果)。
我的 build.gradle 配置文件有
defaultConfig {vectorDrawables.useSupportLibrary = true}
设置且未启用 proguard/minify
debuggable true
crunchPngs false
minifyEnabled false
shrinkResources false
splits.abi.enable false
splits.density.enable false
无论如何,我使用 AndroidStudio 检查了编译后的 .apk 文件,并确保我所有的矢量可绘制对象确实存在于 res/drawable 文件夹中,所以它不是 proguard/shrinker 或类似的。
另外我必须提到我在这个项目中使用 androidx
而不是 support
。
所以我尝试了所有可能的图像设置变体:
setImageResource(imgResId);
setImageDrawable(ContextCompat.getDrawable(context, imgResId));
setImageDrawable(AppCompatResources.getDrawable(context, imgResId));
setImageDrawable(VectorDrawableCompat.createFromResource(resources, imgResId));
setImageDrawable(VectorDrawableCompat.create(resources, imgResId, null));
setImageDrawable(ResourcesCompat.getDrawable(resources, imgResId, null));
没有任何结果(实际上结果总是应用程序崩溃)。发送真实的 Theme
而不是 null
也没有帮助。
这是一个常见的 PagerAdapter
并且矢量可绘制图像被动态地设置为每个页面上的相应 ImageView
,所以当你应该(但不是必须) 将其替换为 app:srcCompat="@drawable\ic_img"
.
而且我还尝试将图像包装到选择器中,例如:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/vector_image" />
</selector>
但运气不好 - 崩溃报告发生了一些变化,但最终导致了相同的异常。
以及我发现的任何其他 SO 问题都没有帮助我。
我的矢量可绘制对象使用的渐变只能从 API 24 开始使用。我正在 API 26 设备上测试我的应用程序,但试图通过将 android:fillColor
添加到 [=26] 来替换所有渐变=] 部分和评论渐变部分,如:
<path
android:pathData="M268.177,..."
android:strokeWidth="1"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillColor="#FFEF5E32">
<!--<aapt:attr name="android:fillColor">-->
<!--<gradient-->
<!--android:startY="84.70677"-->
<!--android:startX="284.02185"-->
<!--android:endY="70.083954"-->
<!--android:endX="252.21419"-->
<!--android:type="linear">-->
<!--<item android:offset="0" android:color="#FFEF5E32"/>-->
<!--<item android:offset="1" android:color="#FFF68F32"/>-->
<!--</gradient>-->
<!--</aapt:attr>-->
</path>
运气不好...
我意识到将我的矢量导入 png/webp 很可能会解决问题,但我想使用矢量绘图。
当我为渐变部分应用补丁时,我注意到 AndroidStudio 突出显示了这些渐变部分,说它受 API 24 支持,而我的项目最小 API 是 21。所以我决定检查其他警告,例如:
Very long vector path (1456 characters), which is bad for performance.
Considering reducing precision, removing minor details or rasterizing
vector.
所以我开始怀疑它是一个问题源,因为在 AndroidStudio 的构建 window 中给出了一条错误消息(红色文本)指出:
string too large to encode using UTF-8 written instead as
'STRING_TOO_LARGE'.
但是没有胶水或指向这个问题的根源,它只是说我的项目中某处有一个很长的字符串,所以它可能是预装的领域数据库文件或类似的东西。
最后我在我的一个矢量绘图中发现了一个异常——它是一个包含大约 51k 个字符的路径字符串!当然,在导入时没有警告我(svg 到 xml,使用 AndroidStudio 完成)。
删除此路径解决了崩溃问题,但也丢失了一部分图像。
因此,我使用 Sketch 对一个有问题的路径组进行了分组,导入后得到了 19k 和 24k 字符的 2 个路径,这也不好,但它现在可以正常工作,没有任何崩溃。
顺便说一句,我找不到任何关于 vector/xml 的字符串长度限制的信息,但是 gradle 确实在构建时应用了这个限制,所以它是众所周知的。
并没有官方文档可以找到。
我的应用最小 SDK 是 21,所以不需要添加
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
应用程序 class 因为它只适用于低于 21(无论如何我尝试添加它但没有结果)。
我的 build.gradle 配置文件有
defaultConfig {vectorDrawables.useSupportLibrary = true}
设置且未启用 proguard/minify
debuggable true
crunchPngs false
minifyEnabled false
shrinkResources false
splits.abi.enable false
splits.density.enable false
无论如何,我使用 AndroidStudio 检查了编译后的 .apk 文件,并确保我所有的矢量可绘制对象确实存在于 res/drawable 文件夹中,所以它不是 proguard/shrinker 或类似的。
另外我必须提到我在这个项目中使用 androidx
而不是 support
。
所以我尝试了所有可能的图像设置变体:
setImageResource(imgResId);
setImageDrawable(ContextCompat.getDrawable(context, imgResId));
setImageDrawable(AppCompatResources.getDrawable(context, imgResId));
setImageDrawable(VectorDrawableCompat.createFromResource(resources, imgResId));
setImageDrawable(VectorDrawableCompat.create(resources, imgResId, null));
setImageDrawable(ResourcesCompat.getDrawable(resources, imgResId, null));
没有任何结果(实际上结果总是应用程序崩溃)。发送真实的 Theme
而不是 null
也没有帮助。
这是一个常见的 PagerAdapter
并且矢量可绘制图像被动态地设置为每个页面上的相应 ImageView
,所以当你应该(但不是必须) 将其替换为 app:srcCompat="@drawable\ic_img"
.
而且我还尝试将图像包装到选择器中,例如:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/vector_image" />
</selector>
但运气不好 - 崩溃报告发生了一些变化,但最终导致了相同的异常。
我的矢量可绘制对象使用的渐变只能从 API 24 开始使用。我正在 API 26 设备上测试我的应用程序,但试图通过将 android:fillColor
添加到 [=26] 来替换所有渐变=] 部分和评论渐变部分,如:
<path
android:pathData="M268.177,..."
android:strokeWidth="1"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillColor="#FFEF5E32">
<!--<aapt:attr name="android:fillColor">-->
<!--<gradient-->
<!--android:startY="84.70677"-->
<!--android:startX="284.02185"-->
<!--android:endY="70.083954"-->
<!--android:endX="252.21419"-->
<!--android:type="linear">-->
<!--<item android:offset="0" android:color="#FFEF5E32"/>-->
<!--<item android:offset="1" android:color="#FFF68F32"/>-->
<!--</gradient>-->
<!--</aapt:attr>-->
</path>
运气不好...
我意识到将我的矢量导入 png/webp 很可能会解决问题,但我想使用矢量绘图。
当我为渐变部分应用补丁时,我注意到 AndroidStudio 突出显示了这些渐变部分,说它受 API 24 支持,而我的项目最小 API 是 21。所以我决定检查其他警告,例如:
Very long vector path (1456 characters), which is bad for performance. Considering reducing precision, removing minor details or rasterizing vector.
所以我开始怀疑它是一个问题源,因为在 AndroidStudio 的构建 window 中给出了一条错误消息(红色文本)指出:
string too large to encode using UTF-8 written instead as 'STRING_TOO_LARGE'.
但是没有胶水或指向这个问题的根源,它只是说我的项目中某处有一个很长的字符串,所以它可能是预装的领域数据库文件或类似的东西。
最后我在我的一个矢量绘图中发现了一个异常——它是一个包含大约 51k 个字符的路径字符串!当然,在导入时没有警告我(svg 到 xml,使用 AndroidStudio 完成)。
删除此路径解决了崩溃问题,但也丢失了一部分图像。
因此,我使用 Sketch 对一个有问题的路径组进行了分组,导入后得到了 19k 和 24k 字符的 2 个路径,这也不好,但它现在可以正常工作,没有任何崩溃。
顺便说一句,我找不到任何关于 vector/xml 的字符串长度限制的信息,但是 gradle 确实在构建时应用了这个限制,所以它是众所周知的。