#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 все заработало.