Включение R8 вызывает "android.view.InflateException Ошибка, надувающая класс TextView" в TextView с fontFamily

Я пытаюсь сжать / запутать мою сборку релиза с помощью R8 (AS 3.3), но происходит сбой при попытке наполнить файл XML, в частности, в TextView с помощью fontFamily. Удаление атрибута fontFamily устраняет проблему.

XML-файл:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/blue_linear_gradient"
    tools:context=".login.LoginFragment">

    <ImageView
        android:id="@+id/familyIcon"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_marginTop="32dp"
        app:srcCompat="@drawable/auth_login_icon"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView   <!-- This is line 20 -->
        android:id="@+id/title"
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:lineHeight="24dp"
        android:maxWidth="168dp"
        android:text="@string/login_title"
        android:textAlignment="center"
        android:fontFamily="@font/gotham_bold" <!-- Removing this line fixes it -->
        android:textColor="@color/kineduWhite"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/authForm"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/familyIcon" />

    <include
        android:id="@+id/authForm"
        layout="@layout/auth_form"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="8dp"
        android:maxWidth="324dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/familyIcon" />

    <!-- More views... -->

</androidx.constraintlayout.widget.ConstraintLayout>

Это трассировка стека:

2019-01-17 17:37:26.496 24514-24514/? E/AndroidRuntime: FATAL EXCEPTION: main
    android.view.InflateException: Binary XML file line #20: Binary XML file line #20: Error inflating class TextView
    Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class TextView
    Caused by: java.lang.NullPointerException: Attempt to read from field 'long android.content.res.XmlBlock$Parser.mParseState' on a null object reference
        at android.content.res.XmlBlock$Parser.getAttributeListValue(XmlBlock.java:320)
        at androidx.core.content.res.FontResourcesParserCompat.androidx.core.content.res.FontResourcesParserCompat$FamilyResourceEntry parse(org.xmlpull.v1.XmlPullParser,android.content.res.Resources)(SourceFile:1)
        at androidx.core.content.res.ResourcesCompat.android.graphics.Typeface loadFont(android.content.Context,android.content.res.Resources,android.util.TypedValue,int,int,androidx.core.content.res.ResourcesCompat$FontCallback,android.os.Handler,boolean)(SourceFile:14)
        at androidx.core.content.res.ResourcesCompat.android.graphics.Typeface loadFont(android.content.Context,int,android.util.TypedValue,int,androidx.core.content.res.ResourcesCompat$FontCallback,android.os.Handler,boolean)(SourceFile:3)
        at androidx.core.content.res.ResourcesCompat.android.graphics.Typeface getFont(android.content.Context,int,android.util.TypedValue,int,androidx.core.content.res.ResourcesCompat$FontCallback)(SourceFile:8)
        at androidx.appcompat.widget.TintTypedArray.android.graphics.Typeface getFont(int,int,androidx.core.content.res.ResourcesCompat$FontCallback)(SourceFile:8)
        at androidx.appcompat.widget.AppCompatTextHelper.void updateTypefaceAndStyle(android.content.Context,androidx.appcompat.widget.TintTypedArray)(SourceFile:102)
        at androidx.appcompat.widget.AppCompatTextHelper.void loadFromAttributes(android.util.AttributeSet,int)(SourceFile:59)
        at androidx.appcompat.widget.AppCompatTextView.void <init>(android.content.Context,android.util.AttributeSet,int)(SourceFile:7)
        at androidx.appcompat.widget.AppCompatTextView.void <init>(android.content.Context,android.util.AttributeSet)(SourceFile:2)
        at androidx.appcompat.app.AppCompatViewInflater.androidx.appcompat.widget.AppCompatTextView createTextView(android.content.Context,android.util.AttributeSet)(SourceFile:1)
        at androidx.appcompat.app.AppCompatViewInflater.android.view.View createView(android.view.View,java.lang.String,android.content.Context,android.util.AttributeSet,boolean,boolean,boolean,boolean)(SourceFile:30)
        at androidx.appcompat.app.AppCompatDelegateImpl.void onSubDecorInstalled(android.view.ViewGroup)(SourceFile:89)
                                                        android.view.View createView(android.view.View,java.lang.String,android.content.Context,android.util.AttributeSet)
        at androidx.appcompat.app.AppCompatDelegateImpl.android.view.View onCreateView(android.view.View,java.lang.String,android.content.Context,android.util.AttributeSet)(SourceFile:1)
        at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:189)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:772)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.company.auth.login.LoginFragment.android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle)(SourceFile:7)

Мой шрифт живет в отдельном модуле библиотеки.

XML-файл семейства шрифтов "res / font / gotham-bold.xml" в :core

<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font
        app:fontStyle="normal"
        app:fontWeight="400"
        app:font="@font/gotham_rnd_bold"/>

    <font
        app:fontStyle="italic"
        app:fontWeight="400"
        app:font="@font/gotham_rnd_bold_italic"/>
</font-family>

И фактический шрифт "gotham_rnd_bold.otf" также находится в этом :core модуль под "res / font /

2 ответа

Решение

Я публикую здесь причину, почему R8 разработчики (из вашей проблемы) для лучшей индексации и ссылки.

Это происходит потому, что вы включаете классы программ в свое приложение, которое уже находится в платформе Android. Правило конфигурации Proguard -dontwarn org.xmlpull.v1.** явно отключает эти предупреждения от компилятора.

В идеале, вы не должны включать какие-либо классы в ваше приложение, которое также находится в платформе Android. Вы должны быть в состоянии определить зависимость, которая включает org.xmlpull.*, А затем исключить этот модуль из зависимости. Кажется, что другие успешно сделали это, см., Например, /questions/5738280/nevozmozhno-dobavit-zavisimost-xstream-148-dlya-android-s-pomoschyu-gradle/5738294#5738294. Если вам удастся сделать это, то вы не должны получать никаких предупреждений, даже если вы удалите правило -dontwarn org.xmlpull.v1.**,

Кроме того, вы можете использовать правило -keep class org.xmlpull.** { *;}, Этот трюк, по-видимому, используется другими ( https://github.com/search?q=org.xmlpull.v1+extension=pro&type=Code), но он может быть подвержен ошибкам, так как ваша версия org.xmlpull.* может отличаться от того, что в платформе Android.

Обратите внимание, что мы работаем над изменением поведения R8 таким образом, чтобы он работал с дублирующимися классами таким образом, чтобы классы инфраструктуры Android всегда имели приоритет над классами программы (b/120884788). В принципе, с этим исправлением не нужно вносить ни одно из вышеуказанных изменений.

Вы можете установить собственный шрифт программно, например;

      customText.typeface = ResourcesCompat.getFont(this, 
R.font.your_font)
Другие вопросы по тегам