我正在使用新的FaceBook SDK 3.0。在将图片从URL发布到“我/照片”时,我间歇性地获得了EOFException
。我偶尔会遇到这个错误(约20次中有1次)。
我还必须在获得EOFException
之后添加,如果我再次重新发布,则会成功发布。
因此,暂时我已编码为自动重试,如果我得到EOFException
并且解决方案似乎令人满意。
但我需要知道导致它的原因,这是Android SDK中的一个错误。我用Google搜索了很多东西,却无法得到任何东西。
我发布了日志(出于安全原因删除了我的访问令牌和图片网址)
06-05 15:09:42.585: D/FacebookSDK.Request(16611): Request:
06-05 15:09:42.585: D/FacebookSDK.Request(16611): Id: 9
06-05 15:09:42.585: D/FacebookSDK.Request(16611): URL:https://graph.facebook.com/me/photos?caption=abc&format=json&sdk=android&migration_bundle=fbsdk%3A20121026&access_token=ADBCEFG&url=http%3A%2F%2Ftest.test.test%2Ftest%2Ftest%2F201695%2Ftest%2F18629
06-05 15:09:42.585: D/FacebookSDK.Request(16611): Method: POST
06-05 15:09:42.585: D/FacebookSDK.Request(16611): User-Agent: FBAndroidSDK.3.0.0
06-05 15:09:42.585: D/FacebookSDK.Request(16611): Content-Type: multipart/form-data; boundary=3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f
06-05 15:09:42.585: D/FacebookSDK.Request(16611): Parameters:
06-05 15:09:42.585: D/FacebookSDK.Request(16611): caption: abc
06-05 15:09:42.585: D/FacebookSDK.Request(16611): format: json
06-05 15:09:42.585: D/FacebookSDK.Request(16611): sdk: android
06-05 15:09:42.585: D/FacebookSDK.Request(16611): migration_bundle: fbsdk:20121026
06-05 15:09:42.585: D/FacebookSDK.Request(16611): access_token: ABCDEF
06-05 15:09:42.585: D/FacebookSDK.Request(16611): url: http://test.test.test/test/test/201695/test/18629
06-05 15:09:42.585: D/FacebookSDK.Request(16611): Attachments:
06-05 15:09:42.600: D/FacebookSDK.Response(16611): Response <Error>: java.io.EOFException
答案 0 :(得分:1)
这是HttpURLConnection
相关问题。用于连接的实际套接字是从池中选择的。大多数服务器都创建持久连接(Connection: Keep-Alive
标头),以便重用现有的套接字,这比每次创建一个新套接口便宜。问题来自于这些插座在一段时间内打开,大多数时间为60秒左右,然后它们被关闭而无法重复使用。然而,Android操作系统尝试使用相同的套接字,因为它认为套接字仍然是好的,因为它被分配到同一主机,因此它开始发送等待ACK和其他响应包的包,这些包从未出现,因为套接字是不再开放,虽然它一直在期待一些答案,因此EOFException
。
private static final int MAX_CONNECTIONS = 5;
// ...
static {
System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS));
}
无论您使用Facebook代码并获得EOFException
,只需将其包装在捕获异常的try-catch中,然后重试连接到最大池大小的URL。这是一个方法存根,可以使用(我不知道Facebook SDK,因此TODO
):
private void connect(int retryNumber) {
try {
// TODO your facebook code goes here
} catch (EOFException e) {
if (retryNumber > MAX_CONNECTIONS) {
// TODO handle exception, it's over the limit, so it is a different problem
} else {
// TODO disconnect first, if possible
connect(retryNumber + 1);
}
} catch (Exception e) {
// TODO other exception handling
} finally {
// TODO disconnect, if possible
}
}
当然,您必须在第一次使用0 retryNumber(connect(0);
)调用此方法。
答案 1 :(得分:0)
听起来您可能遇到了一些互联网连接问题。
您可以写一些retrylogic来处理此异常,方法是再次提交,或者查看您用来上传的类是否有办法增加事务的超时时间。