Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
6d8c4dd4
authored
Mar 13, 2015
by
Andrew Lewis
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add workaround for slow okhttp InputStream.close() on API levels 19/20.
parent
a22ccf92
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
52 additions
and
0 deletions
library/src/main/java/com/google/android/exoplayer/upstream/DefaultHttpDataSource.java
library/src/main/java/com/google/android/exoplayer/util/Util.java
library/src/main/java/com/google/android/exoplayer/upstream/DefaultHttpDataSource.java
View file @
6d8c4dd4
...
@@ -18,6 +18,7 @@ package com.google.android.exoplayer.upstream;
...
@@ -18,6 +18,7 @@ package com.google.android.exoplayer.upstream;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.Predicate
;
import
com.google.android.exoplayer.util.Predicate
;
import
com.google.android.exoplayer.util.Util
;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
android.util.Log
;
...
@@ -226,6 +227,7 @@ public class DefaultHttpDataSource implements HttpDataSource {
...
@@ -226,6 +227,7 @@ public class DefaultHttpDataSource implements HttpDataSource {
public
void
close
()
throws
HttpDataSourceException
{
public
void
close
()
throws
HttpDataSourceException
{
try
{
try
{
if
(
inputStream
!=
null
)
{
if
(
inputStream
!=
null
)
{
Util
.
maybeTerminateInputStream
(
connection
,
bytesRemaining
());
try
{
try
{
inputStream
.
close
();
inputStream
.
close
();
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
...
...
library/src/main/java/com/google/android/exoplayer/util/Util.java
View file @
6d8c4dd4
...
@@ -15,12 +15,16 @@
...
@@ -15,12 +15,16 @@
*/
*/
package
com
.
google
.
android
.
exoplayer
.
util
;
package
com
.
google
.
android
.
exoplayer
.
util
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.Method
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.net.URL
;
import
java.text.ParseException
;
import
java.text.ParseException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
...
@@ -57,6 +61,8 @@ public final class Util {
...
@@ -57,6 +61,8 @@ public final class Util {
Pattern
.
compile
(
"^(-)?P(([0-9]*)Y)?(([0-9]*)M)?(([0-9]*)D)?"
Pattern
.
compile
(
"^(-)?P(([0-9]*)Y)?(([0-9]*)M)?(([0-9]*)D)?"
+
"(T(([0-9]*)H)?(([0-9]*)M)?(([0-9.]*)S)?)?$"
);
+
"(T(([0-9]*)H)?(([0-9]*)M)?(([0-9.]*)S)?)?$"
);
private
static
final
long
MAX_BYTES_TO_DRAIN
=
2048
;
private
Util
()
{}
private
Util
()
{}
/**
/**
...
@@ -396,4 +402,48 @@ public final class Util {
...
@@ -396,4 +402,48 @@ public final class Util {
return
intArray
;
return
intArray
;
}
}
/**
* On platform API levels 19 and 20, okhttp's implementation of {@link InputStream#close} can
* block for a long time if the stream has a lot of data remaining. Call this method before
* closing the input stream to make a best effort to cause the input stream to encounter an
* unexpected end of input, working around this issue. On other platform API levels, the method
* does nothing.
*
* @param connection The connection whose {@link InputStream} should be terminated.
* @param bytesRemaining The number of bytes remaining to be read from the input stream if its
* length is known. {@link C#LENGTH_UNBOUNDED} otherwise.
*/
public
static
void
maybeTerminateInputStream
(
HttpURLConnection
connection
,
long
bytesRemaining
)
{
if
(
SDK_INT
!=
19
&&
SDK_INT
!=
20
)
{
return
;
}
try
{
InputStream
inputStream
=
connection
.
getInputStream
();
if
(
bytesRemaining
==
C
.
LENGTH_UNBOUNDED
)
{
// If the input stream has already ended, do nothing. The socket may be re-used.
if
(
inputStream
.
read
()
==
-
1
)
{
return
;
}
}
else
if
(
bytesRemaining
<=
MAX_BYTES_TO_DRAIN
)
{
// There isn't much data left. Prefer to allow it to drain, which may allow the socket to be
// re-used.
return
;
}
String
className
=
inputStream
.
getClass
().
getName
();
if
(
className
.
equals
(
"com.android.okhttp.internal.http.HttpTransport$ChunkedInputStream"
)
||
className
.
equals
(
"com.android.okhttp.internal.http.HttpTransport$FixedLengthInputStream"
))
{
Class
<?>
superclass
=
inputStream
.
getClass
().
getSuperclass
();
Method
unexpectedEndOfInput
=
superclass
.
getDeclaredMethod
(
"unexpectedEndOfInput"
);
unexpectedEndOfInput
.
setAccessible
(
true
);
unexpectedEndOfInput
.
invoke
(
inputStream
);
}
}
catch
(
IOException
e
)
{
// The connection didn't ever have an input stream, or it was closed already.
}
catch
(
Exception
e
)
{
// Something went wrong. The device probably isn't using okhttp.
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment