Нет статического метода saveAttributeDataForStyleable в классе Landroidx/core/view/ViewCompat; или его суперклассы

#java #android

#java #Android

Вопрос:

Я продолжаю получать это исключение в своем приложении для Android при раздувании представления, расположенного из отдельной библиотеки. java.lang.NoSuchMethodError: No static method saveAttributeDataForStyleable in class or its super classes (declaration of 'androidx.core.view.ViewCompat'... .

В других сообщениях, которые я нашел, связанных с этим, предлагается обновить библиотеки поддержки Android, однако я использую библиотеки androidx (androidx.core 1.2.0 и androidx.appcompat 1.2.0). Также обратите внимание, что по сложным деловым причинам я не могу обновить версию androidx.core, используемую в com.myapp (1.2.0), однако я могу изменить версию, используемую в com.mylibrary. Именно поэтому у меня эта проблема в первую очередь.

Я обнаружил, что saveAttributeDataForStyleable он находится в androidx.core 1.3.0, но не в 1.2.0, поэтому я переключил все в com.mylibrary на использование androidx.core 1.2.0. Однако мой com.myapp по-прежнему выдает исключение. Я также уже пытался исключить библиотеку androidx.core из зависимости com.mylibrary в build.gradle com.myapp, чтобы конечное приложение все равно ссылалось на androidx.core 1.2.0, но это также не сработало.

Это приложение com.myapp, в котором есть библиотека com.mylibrary. SimpleView, который имеет исключение inflate, находится в com.mylibrary, который является еще одним моим пакетом, который я опубликовал в mavenLocal(). com.mylibrary использует androidx.core 1.2.0 и androidx.appcompat 1.2.0 .

build.gradle из com.mylibrary:

 {
    implementation("androidx.appcompat:appcompat:1.2.0") {
        exclude group: "androidx.core", module: "core"
    }
    implementation("androidx.core:core:1.2.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.2"){
        exclude group: "androidx.core", module: "core"
    }
}
 

build.gradle из com.myapp:

 
implementation("com.mylibrary") {
    exclude group: "androidx.core", module: "core"
}
 

Полное исключение:

 com.myapp.views:layout/my_layout: Error inflating class com.mylibrary.SimpleView
    Caused by: android.view.InflateException: Binary XML file line #44 in com.myapp.views:layout/my_layout: Error inflating class com.mylibrary.SimpleView
    Caused by: java.lang.reflect.InvocationTargetException: null
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at android.view.LayoutInflater.createView(LayoutInflater.java:854)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
        at com.mylibrary.ParentSubView.<init>(Unknown Source:55)
        at com.mylibrary.ParentView.<init>(Unknown Source:5)
        at com.mylibrary.ParentView.<init>(Unknown Source:16)
        at com.myapp.MyStore.setupParentView(MyStore.kt:94)

     Caused by: java.lang.NoSuchMethodError: No static method saveAttributeDataForStyleable(Landroid/view/View;Landroid/content/Context;[ILandroid/util/AttributeSet;Landroid/content/res/TypedArray;II)V in class Landroidx/core/view/ViewCompat; or its super classes (declaration of 'androidx.core.view.ViewCompat' appears in /data/app/com.myapp/base.apk)
        at androidx.appcompat.widget.AppCompatBackgroundHelper.loadFromAttributes(AppCompatBackgroundHelper.java:51)
        at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:83)
        at com.mylibrary.SimpleView.<init>(Unknown Source:5)
        at com.mylibrary.SimpleView.<init>(Unknown Source:10)
        at com.mylibrary.SimpleView.<init>(Unknown Source:11)
        ... 25 common frames omitted
 

Комментарии:

1. С выходом Core 1.7.0 (и сразу после 1.8.0) вы обнаружите, что все больше и больше библиотек будут использовать более новые версии Core (а AndroidX обновляет зависимости только в том случае, если им действительно нужны новые API из этих зависимостей), и ваша неспособность обновляться будет все больше и больше мешать вам.

2. @ianhanniballake К сожалению, у меня нет com.myapp (того, который использует 1.2.0), но я доведу это до этого бизнеса в надежде, что они что-то изменят.

Ответ №1:

Также обратите внимание, что по сложным деловым причинам я не могу изменить версию androidx.core, используемую в com.myapp, хотя я могу изменить версию, используемую в com.mylibrary, поэтому я застрял с использованием androidx.core: 1.2.0 в первую очередь.

Я понял это. Разбиение сообщения об ошибке:

 java.lang.NoSuchMethodError: No static method saveAttributeDataForStyleable(Landroid/view/View;Landroid/content/Context;[ILandroid/util/AttributeSet;Landroid/content/res/TypedArray;II)V in class Landroidx/core/view/ViewCompat; or its super classes (declaration of 'androidx.core.view.ViewCompat' appears in /data/app/com.myapp/base.apk)
        at androidx.appcompat.widget.AppCompatBackgroundHelper.loadFromAttributes(AppCompatBackgroundHelper.java:51)
        at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:83)
        at com.mylibrary.SimpleView.<init>(Unknown Source:5)
 
  • Это высказывание saveAttributeDataForStyleable отсутствует. Я внедрил androidx.core 1.2.0 и androidx.core 1.3.0 в свой исходный код и смог обнаружить, что saveAttributeDataForStyleable был введен в androidx.core 1.3.0. Это означает, что com.mylibrary.SimpleView, который расширяет AppCompatImageView, каким-то образом все еще ссылается на более новую версию androidx.core (androidx.core.1.3.0 ), когда она компилируется и публикуется как библиотека в моем локальном репозитории maven. Это приводит к моему SimpleView.class файл, в котором все еще есть функция saveAttributeDataForStyleable().
  • Затем, когда com.myapp запускается и переходит к inflate com.mylibrary.SimpleView, он видит вызов saveAttributeDataForStyleable() в AppCompatImageView и пытается его вызвать. Но поскольку com.myapp имеет только androidx.core 1.2.0 в своих зависимостях, он не может найти эту функцию ни в одном из исходных файлов com.myapp. Это то, что подразумевается под No such method...or its super classes (declaration of 'androidx.core.view.ViewCompat' appears in /data/app/com.myapp/base.apk) .

Итак, исходя из вышесказанного, я сделал вывод, что androidx.core 1.3.0 или выше все еще скрывается в моем графике зависимостей com.mylibrary.

Я побежал ./gradle dependencies из com.mylibrary, чтобы обнаружить, что androidx.core фактически преобразуется в androidx.core 1.7.0 из-за зависимости от другой зависимости. Кроме того, androidx.core отображался в стольких местах графика зависимостей, что я просто поместил это в начало моего build.gradle:

 configurations.all {
    resolutionStrategy.eachDependency { details ->
        if (details.requested.group == 'androidx.core') {
            details.useVersion "1.2.0"
        }
    }
}
 

Но тогда я все равно получал исключение. Как androidx.core 1.3.0 все еще попадал в мой проект?

Я, наконец, посмотрел на класс AppCompatBackgroundHelper (что я должен был сделать в первую очередь), и он находится в библиотеке androidx.appcompat. В моем пакете com.mylibrary использовался androidx.appcompat 1.2.0, поэтому я зашел в репозиторий Maven, чтобы посмотреть зависимости appcompat: https://mvnrepository.com/artifact/androidx.appcompat/appcompat

И в версии 1.2.0 вы можете видеть, что его зависимости от компиляции являются androidx.core:1.1.0. Doh. Итак, несмотря на то, что я исключил androidx.core из строки appcompat моего build.gradle , этого недостаточно, потому что AppCompatImageView в этой библиотеке выполняет четкий вызов saveAttributeDataForStyleable() и, таким образом, импортирует файлы androidx.core: 1.3.0 как зависимость в любом случае.

Конечным решением было переключение build.gradle в моем com.mylibrary на:

 {
    implementation("androidx.appcompat:appcompat:1.1.0")
    implementation("androidx.core:core:1.2.0")
  
  
 implementation("androidx.constraintlayout:constraintlayout:2.1.2")
  
}

configurations.all {
    resolutionStrategy.eachDependency { details ->
        if (details.requested.group == 'androidx.core') {
            details.useVersion "1.2.0"
        }
        if (details.requested.group == 'androidx.appcompat') {
            details.useVersion "1.1.0"
        }
    }
 

И я добавил последнюю строку для безопасного измерения.

После компиляции com.mylibrary и публикации в mavenLocal() и импорта в com.myapp все заработало.