Requests canceling does not work with okhttp3-integration
- Dominant language
- Java
- Stars
- 35k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 8
Description
**Glide Version**: 4.6.1
**Integration libraries**: okhttp3-integration 4.6.1@aar, works fine with stock networking
**Device/Android Version**: Samsung SM-T531/4.4, Lenovo K33a42/7.0, stock emulator of Nexus 7 2012/8.0
**Issue details / Repro steps / Use case background**:
Requests for ImageView widgets are not fully canceled. I prepared small demo project for easier problem understanding.
Steps to reproduce:
1. Take this simple demo app: https://github.com/avdovichev/GlideTest and launch it
2. See ImageView widgets arranged into grid. Initially, cells of grid contain placeholder image and with downloading progress they show images with theirs position numbers. In bottom-left corner application also shows last bound position. At this point everything is OK.
3. Scroll down quickly and non-stop to latest position (predefined value is 4000, see current position in bottom-left corner).
4. Once scrolling is completed see that images are not appearing for a long time. This is because requests for recycled ImageViews were not fully canceled. Server log shows that application downloads all images. And even last images were downloaded (appeared on the screen), application still may be downloading images for scrolled positions. This is first problem.
5. After scrolling to the latest position wait for 5-10 minutes to let application download ~1700 - 1800 images.
6. Try to scroll backwards a little - application will freeze or crash. Looks like there are some resources leakage. Logcat output contains complains about buffer allocation failures and many open files. This is the second problem. Most probably caused by first one.
**Glide load line / `GlideModule` (if any) / list Adapter code (if any)**:
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder,
final int position) {
final ImageView v = (ImageView) holder.itemView;
Glide.with(context)
.load("http://45.55.6.132/cards/" + String.valueOf(position + 1) + "/sample.png")
.apply(new RequestOptions().placeholder(R.drawable.placeholder))
.into(v)
;
positionListener.onPositionChange(position); // to refresh last bound position
}
**Layout XML**:
**Stack trace / LogCat**:
--- Android 4.4 ----
04-22 23:27:38.427 6775-6775/com.example.glidetest W/Adreno-EGL: : EGL_BAD_SURFACE
04-22 23:27:38.427 6775-6775/com.example.glidetest W/HardwareRenderer: EGL error: EGL_BAD_SURFACE
04-22 23:27:38.437 6775-6775/com.example.glidetest W/HardwareRenderer: Mountain View, we've had a problem here. Switching back to software rendering.
04-22 23:27:38.547 6775-6775/com.example.glidetest E/Surface: dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: 1717840517
dequeueBuffer failed (Unknown error -1717840517)
Surface::unlockAndPost failed, no locked buffer
04-22 23:27:38.567 6775-6775/com.example.glidetest E/ViewRootImpl: Could not unlock surface
java.lang.IllegalArgumentException
at android.view.Surface.nativeUnlockCanvasAndPost(Native Method)
at android.view.Surface.unlockCanvasAndPost(Surface.java:281)
at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2906)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2805)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2643)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2211)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6630)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
4-22 23:28:13.687 6775-6775/com.example.glidetest W/Glide: Load failed for http://45.55.6.132/cards/3970/sample.png with size [190x285]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There were 2 causes:
java.net.SocketException(socket failed: EMFILE (Too many open files))
java.io.FileNotFoundException(No content provider: http://45.55.6.132/cards/3970/sample.png)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 2): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, REMOTE
--- Android 7.0 ----
04-22 23:53:02.753 30781-30821/com.example.glidetest E/Parcel: dup() failed in Parcel::read, i is 0, fds[i] is -1, fd_count is 1, error: Too many open files
04-22 23:53:02.759 30781-30821/com.example.glidetest E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -22
04-22 23:53:02.760 30781-30821/com.example.glidetest I/Adreno: QueueBuffer: queueBuffer failed
04-22 23:53:02.761 30781-30821/com.example.glidetest W/OpenGLRenderer: swapBuffers encountered EGL error 12301 on 0x9e5ade20, halting rendering...
--- Android 8.0 ----
04-23 00:03:33.329 12746-12746/com.example.glidetest W/Glide: Load failed for http://45.55.6.132/cards/3976/sample.png with size [186x279]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There were 2 causes:
java.net.SocketException(socket failed: EMFILE (Too many open files))
java.io.FileNotFoundException(No content provider: http://45.55.6.132/cards/3976/sample.png)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 2): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, REMOTE
There was 1 cause:
java.net.SocketException(socket failed: EMFILE (Too many open files))
call GlideException#logRootCauses(String) for more detail
Why I use okhttp3 integration:
Android versions prior to 5.0 have TLS v1.2 support turned off by default. Stock networking fails to get images from server where only TLS v1.2 is allowed. okhttp3 library turns TLS v1.2 support on and solves this problem.
Small demo project:
https://github.com/avdovichev/GlideTest
Mountain View, we have a problem :)
Contributor guide
Assessment
This issue has not been assessed yet.