后台服务 java.net.SocketTimeoutException: 10 分钟后连接失败
Background service java.net.SocketTimeoutException: failed to connect after 10 minutes
(抱歉英语不好)我正在为 android tv/set-top box (STB) 开发应用程序。我的某些设备有问题,其他设备工作正常。我希望有人遇到类似的事情或者能给我指明正确的方向。
我使用后台服务定期检查我们服务器上的一些数据。我使用带有 okhttp3 的 retrofit2 进行网络通信。但是 10 分钟后,改造开始 returning 这个异常:
IOException java.net.SocketTimeoutException:15000 毫秒后无法连接到 our.server.org/XX.XX.XXX.XXX(端口 80)
我的第一个想法是,正如它所说的那样,服务器失去了连接。所以我试着从我的电脑上ping它,一切正常。接下来,我检查了机顶盒,连接正常。我构建了另一个应用程序,这个应用程序带有 Activity、视图和按钮。单击按钮时,它会发送与该后台服务相同的请求。这没有问题。如此看来,机顶盒方面也没有任何问题。
所以问题一定是在服务。我这样创建它:
public class UpdateService extends Service {
public UpdateService() {
HandlerThread thread = new HandlerThread("UpdateService:ServiceThread", THREAD_PRIORITY_MORE_FAVORABLE);
thread.start();
mServiceLooper = thread.getLooper();
}
@Override
public void onCreate() {
super.onCreate();
mHandler = new Handler(mServiceLooper);
final Runnable updateRunnable = new Runnable() {
public void run() {
doStuff();
mHandler.postDelayed(this, UPDATE_CHECK_INTERVAL);
}
};
mHandler.post(updateRunnable);
}
private void doStuff() {
VersionService.getInstance().getVersionList(new VersionService.VersionListener() {
@Override
public void onSuccess(ArrayList<VersionObject> data) {
//code here is called for first 10 minutes
}
@Override
public void onFailure() {
//and here after 10 minutes
}
}
public void getVersionList(final VersionListener listener) {
try {
Call<VersionListApiResponse> call = ApiClient.getStbApi().getVersionList();
Response<VersionListApiResponse> response = call.execute();
if (response.isSuccessful())
{
VersionListApiResponse responseObject = response.body();
listener.onSuccess(responseObject.getVersionList());
}
}
catch (RuntimeException | IOException e)
{
listener.onFailure();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
服务器请求如下所示:
public interface ApiStb {
@Headers({
"Accept:application/json",
"Accept-Charset:UTF-8",
"Content-type:application/json;charset=utf-8"
})
@GET("versionList")
Call<VersionListApiResponse> getVersionList();
}
我做错了什么吗?我试图改变周围的一些事情。我在同步和异步中都使用了 Retrofit。我曾尝试降级改造和 okhttp(没有帮助)。我试图更改 onStartCommand 中的 return 值。我已经重写了 onDestroy() 来检查服务是否被终止(不是)。我试图将 postDelayed(delay) 更改为其他值,但服务每次都在 10 分钟后停止,无论延迟是 15 秒还是 60 秒都没有关系。当出现异常时,我尝试重新启动服务,如下所示:
stopService(new Intent(this, UpdateService.class));
startService(new Intent(this, UpdateService.class));
但我没有帮助。唯一有帮助的是 STB 的硬重启,没有别的。重新启动后,它可以正常工作 10 分钟,然后再次开始抛出异常。这是我们自己的服务器和管理员确认,10 分钟后,没有新的请求,因此似乎请求永远不会离开设备。 DNS 转换工作正常(异常消息中的 IP 地址正确)。我曾尝试更改网络请求的连接超时,但即使我等待 2 分钟,它仍然会在该时间后抛出异常。
在所有这些之后,我尝试在另一个 STB(不同 type/vendor)上安装此服务,并且它按预期工作。如果有人能给我任何建议,我将不胜感激。我怀疑这个设备出于某种原因终止了服务,但从未调用过 onDestroy 。还能是别的吗?
受影响的设备是 X96 Amlogic S905X 四核 Android 6.0 电视盒 (link: https://www.alibaba.com/product-detail/X96-Amlogic-S905X-Quad-Core-Android_60599604444.html?s=p )
谢谢。
编辑:可能 duplicate/answer 不相关,我可以很好地捕获连接超时并增加连接超时:
client.setConnectTimeout(10, TimeUnit.MINUTES);
没有帮助。
但是,我有一些新信息:我尝试向使用 UDP 的服务添加一些其他功能,我 运行 遇到了同样的问题。服务工作正常 10 分钟,但后来我不断收到:
java.net.SocketException: sendto failed: EPERM (Operation not permitted)
我想这在某种程度上是相关的?任何帮助将非常感激。
受影响设备(X96 Amlogic S905X 四核 Android 6.0 电视盒)的解决方案是在 Android 清单中添加至少一个 activity。 activity 永远不会向用户显示,但它以某种方式解决了这个问题。
(服务从接收器启动,带有 android.intent.action.BOOT_COMPLETED 的意图过滤器)
(抱歉英语不好)我正在为 android tv/set-top box (STB) 开发应用程序。我的某些设备有问题,其他设备工作正常。我希望有人遇到类似的事情或者能给我指明正确的方向。
我使用后台服务定期检查我们服务器上的一些数据。我使用带有 okhttp3 的 retrofit2 进行网络通信。但是 10 分钟后,改造开始 returning 这个异常:
IOException java.net.SocketTimeoutException:15000 毫秒后无法连接到 our.server.org/XX.XX.XXX.XXX(端口 80)
我的第一个想法是,正如它所说的那样,服务器失去了连接。所以我试着从我的电脑上ping它,一切正常。接下来,我检查了机顶盒,连接正常。我构建了另一个应用程序,这个应用程序带有 Activity、视图和按钮。单击按钮时,它会发送与该后台服务相同的请求。这没有问题。如此看来,机顶盒方面也没有任何问题。 所以问题一定是在服务。我这样创建它:
public class UpdateService extends Service {
public UpdateService() {
HandlerThread thread = new HandlerThread("UpdateService:ServiceThread", THREAD_PRIORITY_MORE_FAVORABLE);
thread.start();
mServiceLooper = thread.getLooper();
}
@Override
public void onCreate() {
super.onCreate();
mHandler = new Handler(mServiceLooper);
final Runnable updateRunnable = new Runnable() {
public void run() {
doStuff();
mHandler.postDelayed(this, UPDATE_CHECK_INTERVAL);
}
};
mHandler.post(updateRunnable);
}
private void doStuff() {
VersionService.getInstance().getVersionList(new VersionService.VersionListener() {
@Override
public void onSuccess(ArrayList<VersionObject> data) {
//code here is called for first 10 minutes
}
@Override
public void onFailure() {
//and here after 10 minutes
}
}
public void getVersionList(final VersionListener listener) {
try {
Call<VersionListApiResponse> call = ApiClient.getStbApi().getVersionList();
Response<VersionListApiResponse> response = call.execute();
if (response.isSuccessful())
{
VersionListApiResponse responseObject = response.body();
listener.onSuccess(responseObject.getVersionList());
}
}
catch (RuntimeException | IOException e)
{
listener.onFailure();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
服务器请求如下所示:
public interface ApiStb {
@Headers({
"Accept:application/json",
"Accept-Charset:UTF-8",
"Content-type:application/json;charset=utf-8"
})
@GET("versionList")
Call<VersionListApiResponse> getVersionList();
}
我做错了什么吗?我试图改变周围的一些事情。我在同步和异步中都使用了 Retrofit。我曾尝试降级改造和 okhttp(没有帮助)。我试图更改 onStartCommand 中的 return 值。我已经重写了 onDestroy() 来检查服务是否被终止(不是)。我试图将 postDelayed(delay) 更改为其他值,但服务每次都在 10 分钟后停止,无论延迟是 15 秒还是 60 秒都没有关系。当出现异常时,我尝试重新启动服务,如下所示:
stopService(new Intent(this, UpdateService.class));
startService(new Intent(this, UpdateService.class));
但我没有帮助。唯一有帮助的是 STB 的硬重启,没有别的。重新启动后,它可以正常工作 10 分钟,然后再次开始抛出异常。这是我们自己的服务器和管理员确认,10 分钟后,没有新的请求,因此似乎请求永远不会离开设备。 DNS 转换工作正常(异常消息中的 IP 地址正确)。我曾尝试更改网络请求的连接超时,但即使我等待 2 分钟,它仍然会在该时间后抛出异常。
在所有这些之后,我尝试在另一个 STB(不同 type/vendor)上安装此服务,并且它按预期工作。如果有人能给我任何建议,我将不胜感激。我怀疑这个设备出于某种原因终止了服务,但从未调用过 onDestroy 。还能是别的吗?
受影响的设备是 X96 Amlogic S905X 四核 Android 6.0 电视盒 (link: https://www.alibaba.com/product-detail/X96-Amlogic-S905X-Quad-Core-Android_60599604444.html?s=p )
谢谢。
编辑:可能 duplicate/answer 不相关,我可以很好地捕获连接超时并增加连接超时:
client.setConnectTimeout(10, TimeUnit.MINUTES);
没有帮助。
但是,我有一些新信息:我尝试向使用 UDP 的服务添加一些其他功能,我 运行 遇到了同样的问题。服务工作正常 10 分钟,但后来我不断收到:
java.net.SocketException: sendto failed: EPERM (Operation not permitted)
我想这在某种程度上是相关的?任何帮助将非常感激。
受影响设备(X96 Amlogic S905X 四核 Android 6.0 电视盒)的解决方案是在 Android 清单中添加至少一个 activity。 activity 永远不会向用户显示,但它以某种方式解决了这个问题。
(服务从接收器启动,带有 android.intent.action.BOOT_COMPLETED 的意图过滤器)