Android Support 23.3.0 中对vector的支持

现象

Support包升级到23.3.0后,在5.0之前的机器上,对ImageView设置src,或者对AppCompatImageView设置app:srcCompat(item为vector的select资源),应用程序会crash。

根据Google的介绍:

For AppCompat users, we’ve decided to remove the functionality which let you use vector drawables from resources on pre-Lollipop devices due to issues found in the implementation in version 23.2.0/23.2.1 [https://goo.gl/u5suZB, https://goo.gl/fW5Tyd]. Using app:srcCompat and setImageResource() continues to work.

由于存在bug,在23.3.0中已经移除了在pre-Lollipop设备上使用资源获取vector drawable的支持。

分析

根据应用的crash报告:

Caused by android.content.res.Resources$NotFoundException
android.content.res.Resources.loadDrawable (Resources.java:1923)
android.content.res.Resources.getDrawable (Resources.java:664)
android.graphics.drawable.StateListDrawable.inflate (StateListDrawable.java:173)
android.graphics.drawable.Drawable.createFromXmlInner (Drawable.java:867)

以上为部分堆栈

select对应到会创建StateListDrawable实例,并会分析该xml中的item创建相应的drawable。

我们都知道,当我们使用Support包时并将我们的Activity继承AppCompatActivity时,在setContentView的时候会使用AppCompatViewInflater来创建View,将TextView实例化成AppCompatTextView,将ImageView实例化成AppCompatImageView。

而在AppCompatImageView的构造函数中,会通过TintContextWrapper来使用TintResources劫持Resouces的getDrawable方法。

而在23.2.0中,该方法的代码如下:

@Override
public Drawable getDrawable(int id) throws NotFoundException {
    return  AppCompatDrawableManager.get().onDrawableLoadedFromResources(mContext, this, id);
}

会直接调用AppCompatDrawableManager.get,使得在5.0之前的版本也支持vectorDrawable。

而在23.3.0中,该方法代码修改如下:

@Override
public Drawable getDrawable(int id) throws NotFoundException {
    Drawable d = super.getDrawable(id);
    Context context = mContextRef.get();
    if (d != null && context != null) {
        AppCompatDrawableManager.get().tintDrawableUsingColorFilter(context, id, d);
    }
    return d;
}

会先调用super的getDrawable方法,由于在5.0之前的版本中,Drawable找不到vector标签,抛出了NotFoundException导致应用的crash。

而5.0之后的版本,Drawable已经支持vector表情的解析了,所以不存在这个问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容