安卓矢量图:使用Support库的vectorDrawables.useSupportLibrary = true导致应用停止运行。

46

如果我在Gradle中使用vectorDrawables.useSupportLibrary = true,然后运行应用程序,它会意外停止。如果我删除vectorDrawables.useSupportLibrary = true,应用程序就能正常工作。

我的Gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
        applicationId "com.helikanon.firstapp"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.0'
    compile 'com.android.support:design:25.1.0'
    compile 'com.jakewharton:butterknife:8.4.0'
    compile 'com.android.support:support-v4:25.1.0'
    testCompile 'junit:junit:4.12'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
    compile 'uk.co.chrisjenx:calligraphy:2.2.0'
    compile 'com.google.android.gms:play-services-ads:10.0.1'
}

错误:

E/AndroidRuntime: FATAL EXCEPTION: main
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.helikanon.firstapp/com.helikanon.firstapp.activities.MainActivity}: android.view.InflateException: Binary XML file line #62: Error inflating class Button
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
                      at android.app.ActivityThread.access$600(ActivityThread.java:130)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
                      at android.os.Handler.dispatchMessage(Handler.java:99)
                      at android.os.Looper.loop(Looper.java:137)
                      at android.app.ActivityThread.main(ActivityThread.java:4745)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:511)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                      at dalvik.system.NativeStart.main(Native Method)
                   Caused by: android.view.InflateException: Binary XML file line #62: Error inflating class Button
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
.
.
.

当我使用Api 16和Api 19时,应用程序会崩溃,但当我使用Api 23时,它可以正常工作。


请看这篇文章 - http://chris.banes.me/2016/02/25/appcompat-vector/。我也遇到了这个问题。 - Gurupad Mamadapur
我按照这篇文章所做的一切,但仍然出现错误。 - Alexander
我以为你想知道崩溃的原因。无论如何,你使用的Gradle版本是什么? - Gurupad Mamadapur
Gradle版本为2.2.3。 - Alexander
我需要添加vectorDrawables.useSupportLibrary = true,因为我使用矢量图标,并且应用程序必须在API 21以下的矢量图标下正常工作(例如drawable tint)。 - Alexander
你仍然可以使用vectorDrawables.useSupportLibrary = true,只需使用ImageButton而不是Button。 - Ely Dantas
5个回答

43

在安卓5.0以下的设备中,你不能将 矢量图 用于除了 ImageView 以外的任何视图中。

请参考谷歌开发者回答的栈溢出问题解答

对于AppCompat用户,在版本23.2.0/23.2.1中实现存在问题,因此我们决定从资源中删除让你在安卓5.0以下设备上使用矢量图的功能[https://code.google.com/p/android/issues/detail?id=205236, https://code.google.com/p/android/issues/detail?id=204708]。但是使用 app:srcCompatsetImageResource() 仍然有效。

如果你想要在安卓5.0以下设备中使用矢量图,可以通过将其转换为drawable并进行程序设置来实现。

Drawable drawable;

if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
     drawable = context.getResources().getDrawable(drawableResId, context.getTheme());
} else {
     drawable = VectorDrawableCompat.create(context.getResources(), drawableResId, context.getTheme());
}

button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);

2
ContextCompat.getDrawable() doesn't support vector drawables, using AndroidX provided method does: AppCompatResources.getDrawable(context, R.drawable.image) - Ely Dantas

23

我正在进行一项实践项目,旨在学习 Android 中的后台任务和服务。当我拉取他们的示例代码时,最初由于错误,它无法编译。因此,我在应用程序的build.gradle文件中添加了以下标记,以解决编译问题:

android {
    defaultConfig{
        vectorDrawables.useSupportLibrary = true
    }
}

现在,当我添加了这个配置后,我的应用程序也开始像OP描述的那样在Microsoft Android模拟器中崩溃。

由于我当前的重点是学习后台任务,所以我想开始调试我的应用程序。因此,我又删除了上述配置设置。除此之外,我还删除了一个可绘制资源的

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="80dp"
    android:height="80dp"
    android:viewportWidth="24"
    android:viewportHeight="24">

    <path
        android:fillColor="@color/colorAccent"
        android:pathData="M16.01 7L16 3h-2v4h-4V3H8v4h-0.01C7 6.99 6 7.99 6 8.99v5.49L9.5
18v3h5v-3l3.5-3.51v-5.5c0-1-1-2-1.99-1.99z" />
    <path
        android:pathData="M0 0h24v24H0z" />
</vector>

移除后,它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="80dp"
    android:height="80dp"
    android:viewportWidth="24"
    android:viewportHeight="24">

    <path
        android:pathData="M16.01 7L16 3h-2v4h-4V3H8v4h-0.01C7 6.99 6 7.99 6 8.99v5.49L9.5
18v3h5v-3l3.5-3.51v-5.5c0-1-1-2-1.99-1.99z" />
    <path
        android:pathData="M0 0h24v24H0z" />
</vector>

我的MS Android模拟器装有Kitkat(4.4)。根据Vipul的接受答案,由于我的应用程序尝试在Android的早期版本上使用矢量可绘制对象,所以我的代码崩溃了。


9

要使用VectorDrawableCompat,您需要设置:

android.defaultConfig.vectorDrawables.useSupportLibrary = true

要使用VectorDrawableCompat,您需要对项目进行两个修改。首先,在build.gradle文件中设置android.defaultConfig.vectorDrawables.useSupportLibrary = true ,其次,使用app:srcCompat而不是android:src来引用矢量图。

  1. Go to your build.gradle(Module: app) and add following line to android block. It should look like that.

    android {
        compileSdkVersion 27
        defaultConfig {
            applicationId "..."
            minSdkVersion 15
            targetSdkVersion 27
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            vectorDrawables.useSupportLibrary = true // <------
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    }
    
  2. Refer to the source as srcCompat to allow your application to use vector graphics.

    app:srcCompat="@drawable/plane"


3
如果android.defaultConfig.已经嵌套在android { defaultConfig { } }的代码块中,你就不需要再次指定它。 - Antimonit

6

如果您的minSdkVersion大于或等于21,则不需要此操作。

Android 5.0官方支持矢量图形。

https://developer.android.com/guide/topics/graphics/vector-drawable-resources

更新:如StuStirling所提到,在API24以下(Android 7.0),如果在矢量文件中引用其他资源,则需要执行此操作。

更新:

如果您已删除vectorDrawables.useSupportLibrary = true,请分析APK以查找从矢量图生成的pngs。如果您在可绘制项中找到像xxxhdpi-v4这样的内容,请恢复使用useSupportLibrary代码行。 (我没有从矢量图中引用其他可绘制项)


7
并不完全准确。如果要在小于24的向量文件中引用其他资源,需要添加useSupportLibrary = true - StuStirling

3
在您的情况下,问题在于Button不是ImageView的子类。 ImageView或其子类(例如ImageButtonFloatingActionButton)可以使用新的app:srcCompat属性来引用矢量可绘制图形。
要支持矢量可绘制和动画矢量可绘制,您需要添加:
android {
    defaultConfig {
         vectorDrawables.useSupportLibrary = true
    }

请使用app:srcCompat

<ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  app:srcCompat="@drawable/ic_add" />

你可以通过 AndroidX 提供的以下方法将矢量图转换成可绘制的形式,从而仍然可以使用你的 Vector Drawable:
val drawable = AppCompatResources.getDrawable(context, R.drawable.loading_indeterminate)

https://developer.android.com/guide/topics/graphics/vector-drawable-resources

https://medium.com/androiddevelopers/using-vector-assets-in-android-apps-4318fd662eb9


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接