我的应用程序使用 Android 的 Picasso 库从 flickr 加载图像。奇怪的是,不久前将我的应用程序迁移到 Kotlin 后,它工作得很好,但现在我开始出现“随机”503 错误。
我已经在 flickr 控制面板中为每个图像设置了所有权限,因此它们完全公开,并将安全性设置为最低级别,但无济于事。
起初我认为降低 flickr 的安全性是关键,但这是错误的,因为我仍然遇到这个问题。也许它与 Kotlin 迁移根本无关,但我记得不久前它还运行良好。
奇怪的是,如果我调试并复制 url 并将其粘贴到浏览器中,它就会正常加载。
接下来是我加载主屏幕图像的方法:
private fun setTodaysThoughtPainting() {
binding!!.ivTtodaysThought.setOnClickListener { v: View? -> startThoughtActivity("") }
val isTodayThought = AWPreferences.todayThoughtPrefIsToday(this)
mainPainting = mainViewModel!!.getTodaysPainting(isTodayThought)
//FLICKR URL EXAMPLE: mainPainting.setUrl("https://live.staticflickr.com/xxx/xxx_xxx_o_d.jpg");
if (mainPainting != null) {
Picasso.get().load(mainPainting!!.url)
.transform(RoundedTransformation(cornerRadius, 0))
.into(binding!!.ivTtodaysThought, object : Callback {
override fun onSuccess() {
trackId = mainViewModel!!.getTodaysTrack(isTodayThought)
mainThought = mainViewModel!!.getTodaysThought(
mainPainting,
isTodayThought,
idLanguage,
trackId
)
if (mainThought != null) {
setMainShortenThought(mainThought!!)
setMainThoughtDate(Calendar.getInstance())
binding!!.ivTtodaysThought.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
binding!!.ivTtodaysThought.viewTreeObserver.removeOnGlobalLayoutListener(
this
)
val realImgSize = ImageHelper.getRealImageSize(
binding!!.ivTtodaysThought
)
setThoughtMargin(realImgSize[0])
}
})
}
}
override fun onError(e: Exception) {
e.printStackTrace()
}
})
}
}
接下来我可以尝试什么?
编辑1:
这是毕加索堆栈跟踪:
2022-06-15 23:59:03.231 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.233 32258-32258/com.xxx.xxx W/System.err: at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.233 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
2022-06-15 23:59:03.282 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.282 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err: at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
编辑1:
我终于发现这个问题与毕加索无关
我将图像存储在 Flickr 中,我的结论是 Flickr 团队可能已经做出了更改(例如安全更改或其他),因为我尝试使用不同的域测试图像,具体来说是 this 及其工作。我已经写信给 Flickr 支持,但还没有回复。
编辑2:
这没有任何意义,但是当每个图像的配置相同时,有些图像可以工作,有些图像不能。
我知道这个问题,但由于某种原因它适用于 Glide 库而不是 Picasso 库。
我还收到 503 错误,这意味着“服务不可用”。起初我也认为这个问题与 Flickr 服务器有关,但我不能 100% 确定它是否确实是一个问题或者它是这样设计的。我猜测 Flickr 对您可以使用免费套餐发出的请求数量有限制,当/如果您超过该限制,您将收到 503 错误。
我的猜测是 Glide 正在对请求进行排队,而 Picasso 则没有。我实际上创建了一个单独的类来测试这个理论,在其中我处理图像请求的排队并且它起作用了。
如果我的回答对您有任何帮助,请告诉我。
我也遇到了 flickr 的 503 错误。唯一的区别是我将 Coil 与 Compose 一起使用。就我而言,我刚刚添加了标头并停止接收 503 错误。
@Composable
private fun PhotoItem(
photoUrl: String,
) {
val model = ImageRequest.Builder(LocalContext.current)
.data(photoUrl)
.addHeader("Accept-Encoding", "keep-alive")
.addHeader("Connection", "gzip, deflate, br")
.addHeader("User-Agent", "SomeUserAgent")
.build()
AsyncImage(
modifier = Modifier
.fillMaxWidth(),
model = model,
contentDescription = null,
onState = { state ->
when (state) {
is AsyncImagePainter.State.Error -> {
// logs
}
else -> {}
}
}
)
}
仍然不知道它是否有帮助,因为后来它也开始在没有标题的情况下工作。
好吧,经过大量时间和头痛之后,我终于找到了解决方案。
显然(根据我的调查)问题来自于 Android 关于 https 和 http 连接的安全限制。由于默认情况下禁用 Marshmallow http 连接,因此我找到的工作解决方案是在 AndroidManifest.xml 中的“application”标记中添加下一个设置,以删除此限制。
android:usesCleartextTraffic="true"
我不知道这是否是最好的解决方案,甚至不知道它是否安全,但考虑到我目前在这方面投入了大量时间,我会这样保留它。
我认为正确的解决方案应该朝以下方向发展:
https://stackoverflow.com/a/61890208/2807741
但是我做了快速测试,但没有成功。
我受够了这个,看似解决方案最终却并非如此。今天我再次测试,即使设置了
android:usesCleartextTraffic="true"
,使用 Picasso 加载图像时我也会收到 http 503。