API 22启动AnimatedVectorDrawable时触发NullPointerException问题求助
API 22设备上AnimatedVectorDrawable空指针问题分析与修复
嘿,这个问题我在做兼容适配的时候碰到过好几次,核心原因是Android 5.1(API22)系统对AnimatedVectorDrawable的实现有坑,咱们一步步来理清楚:
为什么会出现这个空指针?
在API21到API22的系统里,ImageView.getDrawable()获取设置在android:src上的动画资源时,返回的对象大概率不是你预期的AnimatedVectorDrawable——系统会偷偷把它包装成一个普通的VectorDrawable实例。这时候你强行转成AnimatedVectorDrawable再调用start(),要么直接报类型转换异常,要么因为转换后对象内部状态异常,触发NullPointerException。
另外API22的AnimatedVectorDrawable初始化逻辑还有bug,哪怕你资源写得没问题,系统也可能没正确绑定动画控制器,导致调用start()时找不到核心对象抛出空指针。
靠谱的修复方案
1. 用AndroidX的兼容库(最推荐)
直接用AnimatedVectorDrawableCompat来统一处理所有版本的动画,彻底避开系统原生的坑:
- 先确保项目依赖了AndroidX core库(版本可以根据你的项目调整):
implementation "androidx.core:core-ktx:1.12.0" - 布局里把
android:src换成app:srcCompat来引用动画资源:<ImageView android:id="@+id/anim_img" app:srcCompat="@drawable/your_animated_vector_drawable" android:layout_width="wrap_content" android:layout_height="wrap_content"/> - 代码里直接通过兼容库创建并启动动画:
Kotlin版本更简洁:ImageView animImg = findViewById(R.id.anim_img); AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(this, R.drawable.your_animated_vector_drawable); animImg.setImageDrawable(avd); if (avd != null) { avd.start(); }val animImg = findViewById<ImageView>(R.id.anim_img) AnimatedVectorDrawableCompat.create(this, R.drawable.your_animated_vector_drawable)?.let { avd -> animImg.setImageDrawable(avd) avd.start() }
2. 针对API22做单独兼容(临时方案)
如果暂时不想改兼容库,也可以加版本判断,直接通过资源ID重新创建动画对象,绕开getDrawable()的坑:
ImageView animImg = findViewById(R.id.anim_img); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1) { // 只针对API22单独处理 AnimatedVectorDrawable avd = (AnimatedVectorDrawable) getDrawable(R.drawable.your_animated_vector_drawable); animImg.setImageDrawable(avd); if (avd != null) avd.start(); } else { // 其他版本用原有逻辑 AnimatedVectorDrawable avd = (AnimatedVectorDrawable) animImg.getDrawable(); if (avd != null) avd.start(); }
不过这个方案需要维护版本分支,长期来看不如兼容库省心。
3. 检查动画资源的合法性
最后也可以确认下你的AnimatedVectorDrawable资源有没有问题:
- 确保
<animated-vector>里的android:drawable引用的是正确的VectorDrawable - 动画
<target>的android:name要和VectorDrawable里的路径名称完全一致
有时候资源的小问题在高版本系统会被兼容,但API22会直接导致初始化失败,触发空指针。
内容的提问来源于stack exchange,提问作者Keysaw
相关产品推荐
相关产品推荐

