bumptech / glide

An image loading and caching library for Android focused on smooth scrolling

Home Page:https://bumptech.github.io/glide/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Load GIF from URL fail

AliAl-Hadidi opened this issue · comments

First I want to thank you for this awesome library. It's help me to play gif in imageview, after two weeks of try and search I found that Glide better than all other libraries.
But when try load gif (its size more than 200KB) from url Glide fail to load url and appear error drawable. this is my code:

Glide.with(this)
          .load(gif_url)
          .asGif()
          .error(getResources().getDrawable(R.drawable.error))
          .into(imageview);

I try loading same url by Ion library and It work normal.
Internet is slow in my country but despite this Ion work fine and Glide not.
my questions are:

  • Is there way to increase Glide ability in loading url to be like Ion?
  • Is there any other one have like problem or all works fine with them? I don't want to publish my app and get review that gif not work.

If there is no answer to Q1 I have no way only to download gif by Ion and then showing it by Glide and this is code i write to do:

Ion.with(this)
       load(gif_url)
       .write(file)
       .setCallback(new FutureCallback<File>() {
         @Override
        public void onCompleted(Exception e, File result) {
            Glide.with(getBaseContext())
                      .load(result)
                        .asGif()
                         .diskCacheStrategy(DiskCacheStrategy.NONE )
                           .error(getResources().getDrawable(R.drawable.erorr))
                            .into(imageview);
                                }
                            });

Please tell me if you have any suggestions to fix this problem.

Thank you very much for making Gilde and I hope get answers
Sorry for my weak English

Quicktip: you don't need to getDrawable(), just do .error(R.drawable.error).

Can you share a gif url so we can check it?

Check your LogCat output for what the error is:

  • you can attach a .listener() and print the stack trace in onException
    (careful, the Exception may be null)
  • if it's a SocketTimeoutException see #432
  • if it's a decoding error validate that you're really trying to load a file with GIF format

You'll also likely to run into #358 where the downloaded gif is re-encoded into the cache and it's slow.

Sidenote: Usually if one has the conscience to apologize for bad English they're already speaking well enough. ;)

Thank Robert for answer and tip

Here is one of urls I get error with:
http://i.giphy.com/cgzW4StbNnuuc.gif

I check LogCat and the error is SocketTimeoutException and this is full LogCat:

3323-3323/? W/System.err﹕ java.net.SocketTimeoutException
3323-3323/? W/System.err﹕ at java.net.PlainSocketImpl.read(PlainSocketImpl.java:491)
3323-3323/? W/System.err﹕ at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
3323-3323/? W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
3323-3323/? W/System.err﹕ at java.io.InputStream.read(InputStream.java:162)
3323-3323/? W/System.err﹕ at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
3323-3323/? W/System.err﹕ at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.Util.readAsciiLine(Util.java:316)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
3323-3323/? W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:503)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.data.HttpUrlFetcher.loadDataWithRedirects(HttpUrlFetcher.java:83)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.data.HttpUrlFetcher.loadData(HttpUrlFetcher.java:46)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.data.HttpUrlFetcher.loadData(HttpUrlFetcher.java:20)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.engine.DecodeJob.decodeSource(DecodeJob.java:170)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.engine.DecodeJob.decodeFromSource(DecodeJob.java:128)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.engine.EngineRunnable.decodeFromSource(EngineRunnable.java:122)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:101)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58)
3323-3323/? W/System.err﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
3323-3323/? W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
3323-3323/? W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
3323-3323/? W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
3323-3323/? W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
3323-3323/? W/System.err﹕ at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)

I check #423 but didn't know to fix problem because I get error when use Glide alone without any use of okhttp code, Sorry if I wrong but I'am still beginner in android.

I expect the error because my too bad internet, So can you check above gif url with Gilde an see is it work fine.

I wrote note about English because I don't someone see my issue and say What this speak!!
So I really sorry for my weak English :)

Yep, that's a nice 1.2MB GIF file, which takes a while to download even on WiFi. I should have linked #348 too, which tells you why it doesn't work. Sam's comment is the key, the default networking and default timeout may not be suitable for your app, especially with a low-end network. Glide is not a networking library, it uses them through integration libraries. So in order to set bigger timeouts you will need to use some networking library. That's where #432 comes in and tells you what are the steps. (Not 423, I guess that's just a typo.)

Note: it may be confusing to see com.android.okhttp in your stack trace. That's becuase since Android 4.4 they implemented Java's HttpURLConnection with a version of okhttp. The difference is that com.squareup.okhttp is the real independent networking library which integrates through okhttp-integration into Glide.

Oh Yes Robert I was mean #432 , Sorry!

I follow Sam's links to fix problem and this steps that I do (tell me if one of them is wrong):
1- Add Gradle compile

compile 'com.github.bumptech.glide:okhttp-integration:1.3.0'
compile 'com.squareup.okhttp:okhttp:2.4.0'

2- Add GlideModule class

public class MyGlideModule implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // Do nothing.
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }
}

3- Add metadata to Manifest.xml and class to proguard

<meta-data
            android:name="example.test.MyGlideModule"
            android:value="GlideModule" />

4- Add Glide with okHttp (this what I found when search in issues because it first time to use okHttp):

Glide glide = Glide.get(this);
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(15, TimeUnit.SECONDS);
        client.setReadTimeout(15,TimeUnit.SECONDS);
        OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(client);
        glide.register(GlideUrl.class, InputStream.class, factory);

        glide.with(this)
                .load(gif_url)
                .asGif()
                .listener(------)
                ..into(imageview);

After all this steps I get same error SocketTimeoutException although I use 600KB gif url

Why I still get error? and why time out not increase ?

3- Add <meta-data android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule" tools:node=”remove”/> to make sure that the default OkHttp registration is skipped
4- Move the client creation and factory to MyGlideModule (step 2), you're currently registering twice. But sadly a registration just before into() should really take priority :(

How fast are you getting the timeout notification in listener.onException? Is it at least 10 seconds? Try increasing it to few minutes.

If the above two fixes don't change anything, add a breakpoint in OkHttpStreamFetcher to validate:

  • that OkHttp is used: breakpoint stops when you run your app in debug mode
  • that the correct client is used: use the variables view to inspect the client object and check the timeouts on it

Thanks Robert for all this info.
I add meta-data rewrite MyGlideModule as you said:

public class MyGlideModule  implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {

    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(15, TimeUnit.SECONDS);
        client.setReadTimeout(15,TimeUnit.SECONDS);
        OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(client);
        glide.register(GlideUrl.class, InputStream.class, factory);
    }
}

Glide now work fine and better than before but sometimes when load gif size more than 1MB I get error

java.net.SocketTimeoutException: failed to connect to media2.giphy.com/205.185.208.29 (port 443) after 15000ms

Can I make timeout 1 minute or more ? Is this will not effect on app working ?

Hmm, I'm not sure about that, it's a background thread so your UI will work, but the image may come unexpectedly slow for the user. @sjudd will long running image loads block each other visibly?

commented

@TWiStErRob In Glide 3.0, yes, networking calls block one of our thread pool's threads, so long running downloads will block other requests. In Glide 4.0 networking libraries can make async calls, so whether or not long running downloads block other requests depends on the networking library. In Glide 4 by default long running downloads will block other requests because our default networking library is synchronous, but OkHttp and Volley use async requests, so if you use one of those libraries long running downloads will not block other requests.

Thanx @TWiStErRob and @sjudd for explain this details

I will set timeout to 20 sec and this will be good to OkHttp and other app requests

Thank you very much Robert to help me fix this problem.
Regards

commented

Let us know if you need more help