在 drawable 资源中使用属性引用的兼容问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/maosidiaoxian/article/details/82660719

最近在 Buly 崩溃分析里看到一个之前没见过的异常,异常信息为 Can't convert to color: type=0x2
。详细日志如下:

java.lang.RuntimeException:Unable to start activity ComponentInfo{com.parkingwang.iop/com.parkingwang.iop.home.HomeActivity}: android.view.InflateException: Binary XML file line #79: Error inflating class TextView
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2366)
......
java.lang.UnsupportedOperationException:Can't convert to color: type=0x2
android.content.res.TypedArray.getColor(TypedArray.java:327)
android.graphics.drawable.GradientDrawable.inflate(GradientDrawable.java:970)
android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
android.content.res.Resources.loadDrawable(Resources.java:2206)
android.content.res.TypedArray.getDrawable(TypedArray.java:602)
android.widget.TextView.<init>(TextView.java:854)
android.support.v7.widget.AppCompatTextView.<init>(TbsSdkJava)

我在 google 中搜索这个异常信息,在 stackoverflow 上得到了一个答案,地址如下:
https://stackoverflow.com/a/34279007/2673757

I faced the same issue, that was caused by using attributes as a reference to color in xml drawable. As mentioned here on API < 21 you can’t use attrs to color in xml drawable. So only way is to use a reference to a color resource (@color/YOURS_COLOR) or use #RGB format.

意思是,在 API 21(即 Android 5.0) 以下,不支持在 xml 定义的 drawable 里使用属性(像 ?attr/xxx 这一类)来指定颜色。

在这个项目里,之所以会这样使用颜色属性,是因为项目里有一个换肤的需求,而皮肤是内置在应用中的。本来项目中有使用第三方皮肤框架,但是由于有很多新增的 drawable 的颜色都和皮肤有关,采用皮肤框架的方式需要在每个皮肤包项目中也增加相应的 drawable 资源,并且布局里要设置对应的属性,会比较麻烦。考虑到 Android 中的 Theme 可以通过调用 applyStyle(int resId, boolean force) 方法覆盖主题里的属性,那么如果为不同的皮肤定义不同的 style,然后在 Activity 创建时把对应的皮肤 style 覆盖到原来的主题上,在使用的时候直接引用属性就可以减少皮肤相关的代码了。
当时在测试机上试了一下,确定方案可行,但是使用的是 5.0 以上的设备,也没有考虑到 5.0 以下是否兼容,所以才会出此问题。

既然有这个原因,那只能老老实实地把相关代码改成皮肤框架的方案了。

除此之外,在 drawable 资源里通过属性来指定 drawable 在 5.0 以下也是不支持的。如下:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

它会报如下的 xml 解析异常:

......
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file 
line #8: <item> tag requires a 'drawable' attribute or child tag 
defining a drawable
        at 
android.graphics.drawable.LayerDrawable.inflate(LayerDrawable.java:161)
        at 
android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:901)
        at 
android.graphics.drawable.Drawable.createFromXml(Drawable.java:837)
        at android.content.res.Resources.loadDrawable(Resources.java:2182)
        at android.content.res.TypedArray.getDrawable(TypedArray.java:601)

关于这类问题的讨论见 https://issuetracker.google.com/issues/36941443 ,也就是,5.0 之前在 xml 定义的 drawable 中,是不支持通过属性引用的方式来指定 color 或 drawable 资源的,这个特性在 5.0 开始才被实现。

猜你喜欢

转载自blog.csdn.net/maosidiaoxian/article/details/82660719