Раздувание TextView, генерирующее исключение noSuchMethodException для метода addFontWeightStyle () во время процесса надувания - PullRequest
0 голосов
/ 13 февраля 2019

Обновление: Я изменил заголовок, чтобы убрать указание на то, что ExoPlayer имеет какое-либо отношение к происходящему, поскольку мне удалось скопировать это без его использования вообще.

Я решил попытаться изолировать эту ошибку на уровнях API:

Я получил более старый планшет Samsung (Tab S2) под управлением Android 7.0 (Api 24), и ошибка там не возникает.

Я не могу продублировать эту проблему на эмуляторе Nexus 6, используя API 25

Я также пробовал на более новом планшете Samsung (Tab S3) под управлением Android 8.0.0 (Api 26), той же версиикак на телефоне Samsung S7 Edge.Я получил ту же ошибку.

Затем я создал новый эмулятор (Pixel 2 XL) под управлением Api 26 (Oreo 8.0.0), запустил программное обеспечение и получил ту же ошибку.

I тогдасоздал новый эмулятор (Pixel XL) под управлением Api 27 (Oreo 8.1), запустил программное обеспечение и получил ту же ошибку.

Потерял разочарование при попытке проверить это на Android 9 - возникли ошибки при загрузке пакета,Гуглил, чтобы выяснить, что многим людям нужно было работать от имени администратора, чтобы решить эту проблему, сделал это, скопировал загрузки в папку SDK, которую я использую при моем обычном входе в систему, перезапустил Android под моим обычным входом в систему, исправил SDK в соответствии сзапросил из Studio и определил эмулятор, используя 9. Получил ту же ошибку.

Интересно, что в трассировке стека с использованием Pie я получил другой номер строки, где происходит сбой в TypefaceCompat - строка 47 на этот раз, котораяпо крайней мере на экземпляре соответствующего класса (TypefaceCompatApi28Impl).Однако затем stacktrace все еще показывает, что Api21Impl выдает ошибку.Изучение Api28Impl показывает, что он расширяет Api26Impl, который расширяет Api21Impl.Таким образом, похоже, что это просто вопрос о том, что тег не сообщается правильно.Api21Impl является базовым классом, и именно об этом сообщается.

Он все еще не объясняет, почему происходит ошибка, и что с этим делать.

Так что, по крайней мере, это будет выглядетьВ результате этого ограниченного тестирования возникла проблема с Oreo 8.0, которая также существует во всех последующих SDK.

Что с этим делать?

Обновление: Некоторые другие странные вещи - у моего Samsung API 26 (8.0.0), хотя приведенная ниже трассировка стека показывает, что Android пытается использовать TypefaceCompatApi21Impl:

at androidx.core.graphics.TypefaceCompatApi21Impl.<clinit>(TypefaceCompatApi21Impl.java:74)

Эта строкакод в TypefaceCompatApi21Impl выглядит следующим образом:

        try {
            fontFamilyClass = Class.forName(FONT_FAMILY_CLASS);
            fontFamilyCtor = fontFamilyClass.getConstructor();
error here--->            addFontMethod = fontFamilyClass.getMethod(ADD_FONT_WEIGHT_STYLE_METHOD,
                     String.class, Integer.TYPE, Boolean.TYPE);

Странно, что дальше по трассе стека мы видим, как инициализируется класс * Impl:

Метод AppCompatTextView.setTypeface()call (строка 576) Это, в свою очередь, приводит к созданию гарнитуры:

finalTypeface = TypefaceCompat.create(getContext(), tf, style);

Когда вызывается статический метод create (), это, в свою очередь, вызывает запуск статического инициализатора:

public class TypefaceCompat {
    private static final TypefaceCompatBaseImpl sTypefaceCompatImpl;
    static {
        if (Build.VERSION.SDK_INT >= 28) {
            sTypefaceCompatImpl = new TypefaceCompatApi28Impl();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            sTypefaceCompatImpl = new TypefaceCompatApi26Impl();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
                && TypefaceCompatApi24Impl.isUsable()) {
            sTypefaceCompatImpl = new TypefaceCompatApi24Impl();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            sTypefaceCompatImpl = new TypefaceCompatApi21Impl();
        } else {
            sTypefaceCompatImpl = new TypefaceCompatBaseImpl();
        }
    }

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

at androidx.core.graphics.TypefaceCompat.<clinit>(TypefaceCompat.java:49)

фактически является строкой, инициализирующей TypefaceCompatApi26Impl(), что предполагает использование TypefaceCompatApi26Impl (что имеет смысл, учитывая уровень API моего оборудования Samsung), и, тем не менее, трассировка стека показывает TypefaceCompatApi21Impl(), выбрасываяошибка!

Как это возможно?

Другая подсказка - статический инициализатор запускается только один раз.Так как я получаю это только после того, как я запускаю детальный макет (но есть другие макеты, в которых также есть компоненты TextView, которые появляются до этого), с этим макетом должно быть что-то, что как-то отличается.Вот несколько первых компонентов (вплоть до первого определения компонента TextView) в макете:

<?xml version="1.0" encoding="utf-8"?>
<!-- This layout is used by PlaylistDetailFragment -->
<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:id="@+id/item_listitem_constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Layout related to Playlist 'Header' -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.25"
        android:orientation="vertical" />

    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.80"
        android:orientation="vertical" />

    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.90"
        android:orientation="vertical" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/item_list_content_image"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:layout_marginStart="16dp"
        android:layout_marginTop="4dp"
        android:background="?android:attr/selectableItemBackground"
        android:src="@drawable/playlist"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/guideline1"
        app:layout_constraintBottom_toBottomOf="@+id/playlist_detail_description"/>

    <TextView
        android:id="@+id/playlist_detail_list_content_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="end"
        android:text="@string/playlist_title_label"
        android:textAppearance="@android:style/TextAppearance.Material.Small"
        app:layout_constraintTop_toTopOf="@+id/playlist_detail_title"
        app:layout_constraintBottom_toBottomOf="@+id/playlist_detail_title"
        app:layout_constraintRight_toRightOf="@+id/playlist_detail_list_content_description"/>

Я подумал, что, возможно, строка android:textAppearance="@android:style/TextAppearance.Material.Small" в определении TextView по какой-то причине вызывает проблему,но его удаление не дало эффекта - такая же ошибка происходит.

Обновление 15.02.19: Это просто повторилось, на этот раз на том же устройстве Samsung, где раньше этого не былос совершенно другим макетом, который вообще не использует ExoPlayer и фактически использует только стандартные виджеты.В трассировке стека ниже эта строка:

at com.reddragon.cloudframe.PlaylistDetailFragment.onCreateView(PlaylistDetailFragment.java:309)

- это место, где я раздуваю макет:

final View rootView = inflater.inflate(R.layout.playlist_detail, container, false);

Макет включает в себя очень стандартные элементы (TextView, RecyclerView, Guidelines) и т. Д. Вот полная трассировка стека:

2019-02-15 06:31:12.287 10895-10895/com.reddragon.cloudframe E/TypefaceCompatApi21Impl: java.lang.NoSuchMethodException
    java.lang.NoSuchMethodException: addFontWeightStyle [class java.lang.String, int, boolean]
        at java.lang.Class.getMethod(Class.java:2068)
        at java.lang.Class.getMethod(Class.java:1690)
        at androidx.core.graphics.TypefaceCompatApi21Impl.<clinit>(TypefaceCompatApi21Impl.java:74)
        at androidx.core.graphics.TypefaceCompat.<clinit>(TypefaceCompat.java:49)
        at androidx.core.graphics.TypefaceCompat.create(TypefaceCompat.java:190)
        at androidx.appcompat.widget.AppCompatTextView.setTypeface(AppCompatTextView.java:576)
        at androidx.appcompat.widget.AppCompatTextHelper.loadFromAttributes(AppCompatTextHelper.java:217)
        at androidx.appcompat.widget.AppCompatTextView.<init>(AppCompatTextView.java:103)
        at androidx.appcompat.widget.AppCompatTextView.<init>(AppCompatTextView.java:93)
        at androidx.appcompat.app.AppCompatViewInflater.createTextView(AppCompatViewInflater.java:182)
        at androidx.appcompat.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103)
        at androidx.appcompat.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1267)
        at androidx.appcompat.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1317)
        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.rInflate(LayoutInflater.java:866)
        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.reddragon.cloudframe.PlaylistDetailFragment.onCreateView(PlaylistDetailFragment.java:309)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2530)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:887)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1233)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1299)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:688)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2069)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1859)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1814)
        at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1691)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:537)
        at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:170)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
        at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
        at android.view.View.measure(View.java:23297)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:733)
        at com.google.android.material.appbar.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:95)
        at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1556)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:803)
        at android.view.View.measure(View.java:23297)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)

Есть идеи вообще?Это очень странно и крайне разочаровывает!

Кажется, что это не удается на первом TextView, который он пытается надуть, но я не могу понять, почему происходит эта ошибка.Я использую те же виджеты TextView в других макетах этого приложения, они раздуваются очень хорошо!

Обновление 13.02.19: при поиске похожих проблем, обнаруженных мной этот пост .Поскольку в нем упоминалось разное поведение на эмуляторе и физическом, я проверил свою проблему на физическом устройстве (Samsung 7 Edge, Android 8.0.0) и вуаля - без проблем.

РЕДАКТИРОВАТЬ 2/16/19 - но теперь смотрите комментарии вверху этого поста.Я не знаю, почему этого не произошло в моем первоначальном тесте, который я описал здесь, который я делал 2/13, но проблема «вернулась» в Samsung 7 Edge с API 26.

Я удалилпредыдущий эмулятор (Nexus 5, API 27) и создал новый (Nexus 6, API 25) и .... без ошибок!Странно, но эмулятор почему-то запутался, я полагаю ... Было бы неплохо понять, как быстрее устранять неполадки такого рода.

================================

Я работал над приложением (MediaPlayerActivity) с использованием новейшего Exoplayer (2.9.5) и только недавно начал получать ошибкипри попытке раздувать фондовые представления:

2019-02-12 21:36:43.339 25761-25761/E/TypefaceCompatApi21Impl: java.lang.NoSuchMethodException
    java.lang.NoSuchMethodException: addFontWeightStyle [class java.lang.String, int, boolean]
        at java.lang.Class.getMethod(Class.java:2068)
        at java.lang.Class.getMethod(Class.java:1690)
        at androidx.core.graphics.TypefaceCompatApi21Impl.<clinit>(TypefaceCompatApi21Impl.java:74)
        at androidx.core.graphics.TypefaceCompat.<clinit>(TypefaceCompat.java:49)
        at androidx.core.graphics.TypefaceCompat.create(TypefaceCompat.java:190)
        at androidx.appcompat.widget.AppCompatTextView.setTypeface(AppCompatTextView.java:576)
        at androidx.appcompat.widget.AppCompatTextHelper.loadFromAttributes(AppCompatTextHelper.java:217)
        at androidx.appcompat.widget.AppCompatTextView.<init>(AppCompatTextView.java:103)
        at androidx.appcompat.widget.AppCompatTextView.<init>(AppCompatTextView.java:93)
        at androidx.appcompat.app.AppCompatViewInflater.createTextView(AppCompatViewInflater.java:182)
        at androidx.appcompat.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103)
        at androidx.appcompat.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1267)
        at androidx.appcompat.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1317)
        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.rInflate(LayoutInflater.java:866)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.parseInclude(LayoutInflater.java:995)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:859)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at com.google.android.exoplayer2.ui.PlayerControlView.<init>(PlayerControlView.java:296)
        at com.google.android.exoplayer2.ui.PlayerView.<init>(PlayerView.java:452)
        at com.google.android.exoplayer2.ui.PlayerView.<init>(PlayerView.java:304)
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.view.LayoutInflater.createView(LayoutInflater.java:647)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)
        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 MediaPlayerActivity$MediaPagerAdapter.instantiateItem(MediaPlayerActivity.java:676)

Я использую стандартные стоковые представления ExoPlayer - ничего особенного:

Макет из pager_video_item.xml:

<!-- Video Player  -->
<com.google.android.exoplayer2.ui.PlayerView
    android:id="@+id/video_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"/>

Код, с которого начинается ошибка, который находится в экземпляре PagerAdapter:

        case Media.MEDIA_TYPE_VIDEO:
            itemView = mLayoutInflater.inflate(R.layout.pager_video_item, container, false);

mLayoutInflater инициализируется в конструкторе PagerAdapter:

class MediaPagerAdapter extends PagerAdapter {

    final Context mContext;
    final LayoutInflater mLayoutInflater;

    MediaPagerAdapter(Context context) {
        mContext = context;
        mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

Переданный контекст взят из моего *Класс 1111 *, который расширяет androidx.appcompat.app.AppCompatActivity (CFViewPager расширяет ViewPager и просто добавляет некоторую логику для соответствующей обработки событий касания.):

mViewPagerView = findViewById(R.id.activity_media_player_viewpager);
((CFViewPager) mViewPagerView).setAdapter(new MediaPagerAdapter(this));

Я могу собрать и запустить демонстрацию ExoPlayer нау меня такая же машина и она работает.Ясно, что я изменил некоторые настройки в моем приложении, которые сбивают с толку время выполнения.Опять же, раньше это прекрасно работало пару дней назад.

Я поливал различные версии управления версиями и не вижу ничего, что я представил, что могло бы вызвать такое поведение.

Оттрассировка стека, похоже, что он не работает при попытке накачать TextView в PlayerControlView.Но я не знаю, как устранять неполадки.

Что может заставить среду выполнения думать "внезапно", что она не может использовать отражение, чтобы найти метод addFontWeightStyle () в TypefaceCompatApi21Impl.java?

Android Studio - последний стабильный выпуск (3.3.1). Я считаю, что мои файлы Gradle обновлены:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

compileSdkVersion 28
defaultConfig {
    applicationId "mycoolapp.com"
    minSdkVersion 21
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"

Для инструментов сборки установлено значение 28.0.3

У меня естьаннулированные кэши и перезапущенные, перестроенные и т. д.

Спасибо за любые мысли о том, где искать неисправности.

1 Ответ

0 голосов
/ 20 февраля 2019

Эта ошибка уже сообщена команде Android, и, похоже, это исправление, готовое к будущему выпуску:

https://issuetracker.google.com/issues/124274577

Я предполагаю, что они ссылаютсяв будущем выпуске библиотеки AndroidX.

...