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 inonException
(careful, theException
may benull
) - 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?
@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
Let us know if you need more help