我正在使用绑定适配器在回收站视图中加载图像。图像显得很好。在快速滚动的同时,我注意到有时候我的连接被泄露了#39;来自毕加索的消息。
问题来自死图像链接,硬编码我的所有图像网址指向无处为每个图像滚动屏幕上的第一对后产生错误。
W/OkHttpClient: A connection to https://s3-eu-west-1.amazonaws.com/ was leaked. Did you forget to close a response body?
代码基本相同to this sample。
BindingUtils.kt
object BindingUtils {
@BindingAdapter("imageUrl")
@JvmStatic
fun setImageUrl(imageView: ImageView, url: String) {
Picasso.with(imageView.context).load(url).into(imageView)
}
XML
<ImageView
android:id="@+id/imageview_merchant_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primary"
android:scaleType="centerCrop"
app:imageUrl="@{viewModel.background}"/>
gradle这个
implementation "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttpLoggingVersion"
implementation "com.squareup.picasso:picasso:$rootProject.picassoVersion"
retrofitVersion = '2.3.0'
okhttpLoggingVersion = '3.6.0'
picassoVersion = '2.5.2'
我可以看到几个人需要关闭标准Okhttp请求的连接,但看到Picasso加载调用是单行的,这怎么会泄漏?
答案 0 :(得分:2)
引擎盖下Picasso正在使用okhttp3来处理其网络请求。请参阅此处Picasso的NetworkRequestHandler类的代码:https://github.com/square/picasso/blob/0728bb1c619746001c60296d975fbc6bd92a05d2/picasso/src/main/java/com/squareup/picasso/NetworkRequestHandler.java
有一个处理okhttp请求的加载函数:
@Override public Result load(Request request, int networkPolicy) throws IOException {
okhttp3.Request downloaderRequest = createRequest(request, networkPolicy);
Response response = downloader.load(downloaderRequest);
ResponseBody body = response.body();
if (!response.isSuccessful()) {
body.close();
throw new ResponseException(response.code(), request.networkPolicy);
}
// Cache response is only null when the response comes fully from the network. Both completely
// cached and conditionally cached responses will have a non-null cache response.
Picasso.LoadedFrom loadedFrom = response.cacheResponse() == null ? NETWORK : DISK;
// Sometimes response content length is zero when requests are being replayed. Haven't found
// root cause to this but retrying the request seems safe to do so.
if (loadedFrom == DISK && body.contentLength() == 0) {
body.close();
throw new ContentLengthException("Received response with 0 content-length header.");
}
if (loadedFrom == NETWORK && body.contentLength() > 0) {
stats.dispatchDownloadFinished(body.contentLength());
}
InputStream is = body.byteStream();
return new Result(is, loadedFrom);
}
我对Picasso项目并不太熟悉,但似乎在所有情况下都没有关闭响应体对象。你可能已经发现了毕加索的一个错误,可能想在毕加索的github上提出一个问题
答案 1 :(得分:0)
疯狂猜测,如果它必须对您的活动的上下文的泄漏做任何事情。尝试使用 applicationContext
Picasso.with(imageView.context.applicationContext).load(url).into(imageView)