bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.59k stars 6.12k forks source link

GIF artifacts on < Android 4.3 #1123

Open d4rken opened 8 years ago

d4rken commented 8 years ago

GIF artifacts on < Android 4.3

Glide Version: 4.0.0-SNAPSHOT

On first load all looks okay, on second load the gif looks like this on a I9100@4.1.2: device-2016-04-10-183637

Logfile using @TWiStErRob nice logging wrapper :)

// First load from coldstart
04-10 18:35:46.281 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: getRequest()
04-10 18:35:46.291 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: setRequest(com.bumptech.glide.request.SingleRequest@41ff2408)
04-10 18:35:46.346 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: getSize(com.bumptech.glide.request.SingleRequest@41ff2408)
04-10 18:35:46.346 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onSizeReady(com.bumptech.glide.request.SingleRequest@41ff2408, 300, 300)
04-10 18:35:46.441 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onLoadStarted(android.graphics.drawable.BitmapDrawable@41c36a60)
04-10 18:35:46.446 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onStart()
04-10 18:35:46.776 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onResourceReady(com.bumptech.glide.load.resource.gif.GifDrawable@41ae9488, com.bumptech.glide.request.transition.NoTransition@41fed0a8)
// Subsequent second load demonstrating the issue
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: getRequest()
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: getRequest()
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onLoadCleared(android.graphics.drawable.BitmapDrawable@41c36a60)
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: setRequest(null)
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: setRequest(com.bumptech.glide.request.SingleRequest@41ff2408)
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: getSize(com.bumptech.glide.request.SingleRequest@41ff2408)
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onSizeReady(com.bumptech.glide.request.SingleRequest@41ff2408, 300, 300)
04-10 18:36:12.626 16652-16652/eu.thedarken.sdm D/SDM:GlideGif: onResourceReady(com.bumptech.glide.load.resource.gif.GifDrawable@425f1368, com.bumptech.glide.request.transition.NoTransition@41fed0a8)

Code:

public void setState(@NonNull Fragment fragment, @NonNull State state) {
    mState = state;
    if (state == State.WORKING) {
        setVisibility(VISIBLE);
        mEasterEggCounter = 0;
        mIntroContainer.setVisibility(GONE);
        mEmptyContainer.setVisibility(GONE);
        mWorkingContainer.setVisibility(VISIBLE);
        //if (ApiHelper.hasJellyBeanMR2()) {
            Glide.with(fragment)
                    .load(COFFEE_ANIM_ASSET)
                    .apply(new RequestOptions()
                            .format(DecodeFormat.PREFER_RGB_565)
                            .placeholder(R.drawable.sdmanimation)
                            .optionalFitCenter(mWorkingAnimation.getContext()))
                    .into(new LoggingTarget<>(TAG_GIFISSUE, Log.DEBUG, new DrawableImageViewTarget(mWorkingAnimation)));
        //} else {
        //    mWorkingAnimation.setImageResource(R.drawable.graphic_mascot);
        //}
    } else {
       // if (ApiHelper.hasJellyBeanMR2()) {
            Drawable drawable = mWorkingAnimation.getDrawable();
            if (drawable instanceof Animatable) {
                Animatable gif = (Animatable) drawable;
                if (gif.isRunning()) gif.stop();
            }
       // } else {
       //     mWorkingAnimation.setImageResource(R.drawable.graphic_mascot);
       // }
        mWorkingContainer.setVisibility(GONE);
        if (state == State.INTRO) {
            setVisibility(VISIBLE);
            mEmptyContainer.setVisibility(GONE);
            mIntroContainer.setVisibility(VISIBLE);
        } else if (state == State.NORESULTS) {
            setVisibility(VISIBLE);
            mIntroContainer.setVisibility(GONE);
            mEmptyContainer.setVisibility(VISIBLE);
        } else if (state == State.GONE) {
            setVisibility(GONE);
            mIntroContainer.setVisibility(GONE);
            mEmptyContainer.setVisibility(GONE);
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools">

    <LinearLayout
        android:id="@+id/container_intro"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:visibility="gone"
        android:orientation="vertical"
        tools:visibility="visible"
        android:layout_margin="32dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            tools:ignore="UseCompoundDrawables">

            <ImageView
                android:id="@+id/iv_intro_icon"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_marginRight="8dp"
                android:layout_marginEnd="8dp"
                tools:src="@drawable/ic_coffee_white_24dp"/>

            <TextView
                android:id="@+id/tv_intro_title"
                style="@style/TextStyleHeadline"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="start|center_vertical"
                tools:text="@string/navigation_label_explorer"/>
        </LinearLayout>

        <ScrollView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1">

            <TextView
                android:id="@+id/tv_intro_description"
                style="@style/TextStyleBody1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="33dp"
                android:layout_marginStart="33dp"
                android:paddingTop="5dip"
                tools:text="@string/explorer_explanation"/>
        </ScrollView>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/working_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="16dp"
        android:visibility="gone"
        tools:visibility="visible">

        <ImageView
            android:id="@+id/iv_working_animation"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:padding="5dp"
            android:src="@drawable/sdmanimation"/>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/container_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="16dp"
        android:visibility="gone"
        tools:visibility="visible">

        <TextView
            style="@style/TextStyleTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:paddingTop="25dip"
            android:text="@string/list_is_empty"/>
    </LinearLayout>
</merge>
TWiStErRob commented 8 years ago

Can you please share:

d4rken commented 8 years ago

the GIF file

sdmanimation

COFFEE_ANIM_ASSET (is it in src/main/assets?)

Yes.

First load from coldstart" is setState(WORKING) I assume, and "Subsequent second load" is setState(WORKING) again. Was there any other setState(_) called between? (Trying to minimize the *_repro)**

// Coldstart
04-10 19:40:05.131 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: setState(fragment=OverviewFragment{419fa440 #1 id=0x7f0d007a eu.thedarken.sdm.overview.OverviewFragment}, state=INTRO
04-10 19:40:10.611 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: setState(fragment=OverviewFragment{419fa440 #1 id=0x7f0d007a eu.thedarken.sdm.overview.OverviewFragment}, state=WORKING
04-10 19:40:10.731 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.getRequest()
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:10.731 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.setRequest(com.bumptech.glide.request.SingleRequest@41ff52a0)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:10.796 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.getSize(com.bumptech.glide.request.SingleRequest@41ff52a0)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:10.796 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.onSizeReady(com.bumptech.glide.request.SingleRequest@41ff52a0, 300, 300)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:10.906 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.onLoadStarted(android.graphics.drawable.BitmapDrawable@42011780)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:10.906 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.onStart()
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:11.306 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.onResourceReady(com.bumptech.glide.load.resource.gif.GifDrawable@41f7cef0, com.bumptech.glide.request.transition.NoTransition@41fef8c8)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:17.391 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: setState(fragment=OverviewFragment{419fa440 #1 id=0x7f0d007a eu.thedarken.sdm.overview.OverviewFragment}, state=GONE
// Hotstart
04-10 19:40:38.146 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: setState(fragment=OverviewFragment{419fa440 #1 id=0x7f0d007a eu.thedarken.sdm.overview.OverviewFragment}, state=WORKING
04-10 19:40:38.151 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.getRequest()
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.151 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.getRequest()
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.156 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@41ff3258.onLoadCleared(android.graphics.drawable.BitmapDrawable@42011780)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.156 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.setRequest(null)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.156 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.setRequest(com.bumptech.glide.request.SingleRequest@41ff52a0)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.156 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.getSize(com.bumptech.glide.request.SingleRequest@41ff52a0)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.156 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.onSizeReady(com.bumptech.glide.request.SingleRequest@41ff52a0, 300, 300)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:38.161 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: DrawableImageViewTarget@425f4f10.onResourceReady(com.bumptech.glide.load.resource.gif.GifDrawable@425f8920, com.bumptech.glide.request.transition.NoTransition@41fef8c8)
                                                              Target for: android.support.v7.widget.AppCompatImageView@41a786f0
04-10 19:40:39.756 9653-9653/eu.thedarken.sdm D/SDM:GlideGif: setState(fragment=OverviewFragment{419fa440 #1 id=0x7f0d007a eu.thedarken.sdm.overview.OverviewFragment}, state=GONE