我正在使用新的FaceBook SDK 3.0。从URL将图像发布到“我/照片”时,我间歇性地收到了EOFException
。我偶尔会收到此错误(20次中有1次)。
我还必须补充一点,如果我再次尝试发布,则在获取EOFException
之后,它就成功发布了。
因此,暂时我已经编码为如果收到EOFException
可以自动重试一次,并且该解决方案似乎令人满意。
但是我需要知道是什么原因造成的,这是Android SDK中的错误吗?我在Google上搜索了很多,但什么也没得到。
我正在发布日志(出于安全原因删除了我的访问 token 和图像URL)
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
最佳答案
问题
这是与HttpURLConnection
相关的问题。从池中选择用于连接的实际套接字。大多数服务器创建持久连接(Connection: Keep-Alive
header )以便重用现有套接字,这比每次创建一个新套接字都便宜。问题出在以下事实:这些套接字在一定时间段(通常为60秒左右)内打开,然后关闭并且无法重复使用。但是,Android OS尝试使用相同的套接字,因为它认为套接字已分配给同一主机,因此认为它仍然是好的,因此它开始发送等待ACK的包和其他响应包,因为套接字一直没有收到。不再打开,尽管一直在期待一些答案,所以EOFException
。
解决方案
第1步-将池的大小限制为相对较小的数目
private static final int MAX_CONNECTIONS = 5;
// ...
static {
System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS));
}
第2步-实现重试机制
无论您在何处使用Facebook代码并获得
EOFException
,都将其包装在try-catch中,该捕获可捕获异常并重试连接到URL的最大池大小。这是可以使用的方法 stub (我不知道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);
)调用此方法。关于android - Facebook SDK 3 EOFException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16944009/