AnimationDrawable загружается слишком долго - PullRequest
0 голосов
/ 06 мая 2020

Я расширяю ImageView следующим образом:

public class AnimatedTemperatureValveImageView extends AppCompatImageView {

    private AnimationDrawable mAnimation;

    private Boolean mState;

    private Drawable mAnimatedTemperatureValveOnDrawable;

    public AnimatedTemperatureValveImageView(Context context) {
        super(context);
        init();
    }

    public AnimatedTemperatureValveImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AnimatedTemperatureValveImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mAnimatedTemperatureValveOnDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_animated_temperature_valve_on);
    }

    /**
     * Update the image according the state
     *
     * @param state When null, hides the image.
     *              When false, shows the OFF state
     *              When true, shows the ON state
     */
    public void updateState(Boolean state) {
        mState = state;
        if(mState == null) {
            setBackground(null);
        } else if(mState) {
            setBackgroundDrawable(mAnimatedTemperatureValveOnDrawable);
        } else {
            setBackgroundResource(R.drawable.ic_temperature_valve_off);
        }
    }

    public void startAnimationIfNecessary(boolean start) {
        if(this.getBackground() instanceof AnimationDrawable) {
            mAnimation = (AnimationDrawable) this.getBackground();
            if(start && mState) {
                mAnimation.start();
            } else {
                mAnimation.stop();
            }
        }
    }

}

Где ic_tempera_valve_off - это простой файл изображения, а ic_animated_tempera_valve_on - это список анимации, подобный этому ( все изображения в формате webp, не уверен, что это актуально для проблемы):

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/flame_200" android:duration="100" />
    <item android:drawable="@drawable/flame_201" android:duration="100" />
    <item android:drawable="@drawable/flame_202" android:duration="100" />
    <item android:drawable="@drawable/flame_203" android:duration="100" />
    <item android:drawable="@drawable/flame_204" android:duration="100" />
    <item android:drawable="@drawable/flame_205" android:duration="100" />
    <item android:drawable="@drawable/flame_206" android:duration="100" />
    <item android:drawable="@drawable/flame_207" android:duration="100" />
    <item android:drawable="@drawable/flame_208" android:duration="100" />
    <item android:drawable="@drawable/flame_209" android:duration="100" />
    <item android:drawable="@drawable/flame_210" android:duration="100" />
    <item android:drawable="@drawable/flame_211" android:duration="100" />
    <item android:drawable="@drawable/flame_212" android:duration="100" />
    <item android:drawable="@drawable/flame_213" android:duration="100" />
    <item android:drawable="@drawable/flame_214" android:duration="100" />
    <item android:drawable="@drawable/flame_215" android:duration="100" />
    <item android:drawable="@drawable/flame_216" android:duration="100" />
    <item android:drawable="@drawable/flame_217" android:duration="100" />
    <item android:drawable="@drawable/flame_218" android:duration="100" />
    <item android:drawable="@drawable/flame_219" android:duration="100" />
    <item android:drawable="@drawable/flame_220" android:duration="100" />
    <item android:drawable="@drawable/flame_221" android:duration="100" />
    <item android:drawable="@drawable/flame_222" android:duration="100" />
    <item android:drawable="@drawable/flame_223" android:duration="100" />
    <item android:drawable="@drawable/flame_224" android:duration="100" />
</animation-list>

Эти изображения пламени довольно маленькие. Все они вместе занимают около 30 КБ.

Это представление отображается в элементе RecyclerView, который находится внутри фрагмента.

В моем приложении много фоновых потоков, выполняющих разные вещи, но большую часть времени большинство из них находятся в состоянии сна.

Проблема в том, что когда я перехожу к этому фрагменту содержащий этот RV впервые, на его рендеринг уходит много времени, а иногда даже возникает ANR.

Это приложение должно быть запущено на устройстве с Android 4.4.2, поэтому Я не могу использовать профилировщик Android Studio для профилирования приложения.

Однако я использовал старый инструмент DDMS и смог получить трассировку при переходе к этому фрагменту. Вот раздел, который кажется проблемным c: problematic_section

Как видите, загрузка моего пользовательского ImageView занимает около 5,7 секунд, что слишком много .. Однако мне кажется, что это больше связано с событиями GC, чем с загрузкой самих изображений. Потому что иногда это делается намного быстрее. Я вижу несколько GC_FOR_ALLOC событий в секунду в logcat.

Наконец, мои вопросы:

  • Справедливо ли предположить, что проблема, вероятно, связана с тем, что G C часто запускается (слишком много выделений)?
  • Как мне лучше профилировать приложение, имея в виду, что оно работает в Android 4.4.2? (Когда я запускаю приложение на новых устройствах, с лучшим оборудованием и с Android 8 Oreo, у меня нет таких проблем)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...