現(xiàn)象
Support包升級(jí)到23.3.0后练湿,在5.0之前的機(jī)器上箱残,對(duì)ImageView設(shè)置src志笼,或者對(duì)AppCompatImageView設(shè)置app:srcCompat(item為vector的select資源),應(yīng)用程序會(huì)crash韭脊。
根據(jù)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中已經(jīng)移除了在pre-Lollipop設(shè)備上使用資源獲取vector drawable的支持塞帐。
分析
根據(jù)應(yīng)用的crash報(bào)告:
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對(duì)應(yīng)到會(huì)創(chuàng)建StateListDrawable實(shí)例,并會(huì)分析該xml中的item創(chuàng)建相應(yīng)的drawable巍沙。
我們都知道葵姥,當(dāng)我們使用Support包時(shí)并將我們的Activity繼承AppCompatActivity時(shí),在setContentView的時(shí)候會(huì)使用AppCompatViewInflater來創(chuàng)建View赎瞎,將TextView實(shí)例化成AppCompatTextView牌里,將ImageView實(shí)例化成AppCompatImageView颊咬。
而在AppCompatImageView的構(gòu)造函數(shù)中务甥,會(huì)通過TintContextWrapper來使用TintResources劫持Resouces的getDrawable方法牡辽。
而在23.2.0中,該方法的代碼如下:
@Override
public Drawable getDrawable(int id) throws NotFoundException {
return AppCompatDrawableManager.get().onDrawableLoadedFromResources(mContext, this, id);
}
會(huì)直接調(diào)用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;
}
會(huì)先調(diào)用super的getDrawable方法,由于在5.0之前的版本中挺尿,Drawable找不到vector標(biāo)簽奏黑,拋出了NotFoundException導(dǎo)致應(yīng)用的crash。
而5.0之后的版本编矾,Drawable已經(jīng)支持vector表情的解析了熟史,所以不存在這個(gè)問題。