【问题标题】:Background service java.net.SocketTimeoutException: failed to connect after 10 minutes后台服务 java.net.SocketTimeoutException:10 分钟后连接失败
【发布时间】:2017-09-21 12:20:50
【问题描述】:

(抱歉英语不好)我正在为安卓电视/机顶盒(STB)开发应用程序。我对某些设备有问题,其他设备工作正常。我希望有人遇到类似的事情或可以指出正确的方向。

我使用后台服务定期检查我们服务器上的一些数据。我使用 retrofit2 和 okhttp3 进行网络通信。但 10 分钟后,改造开始返回此异常:

IOException java.net.SocketTimeoutException: 在 15000 毫秒后无法连接到 our.server.org/XX.XX.XXX.XXX(端口 80)

我的第一个想法是,正如它所说,服务器失去了连接。所以我试着从我的电脑上ping它,一切正常。接下来,我检查了 STB,连接正常。我已经构建了另一个应用程序,这个带有 Activity、View 和 Button 的应用程序。单击按钮时,它会发送与该后台服务相同的请求。这没有问题。看来,机顶盒方面也没有任何问题。 所以问题必须在服务中。我是这样创建的:

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 中的返回值。我已经覆盖 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(不同类型/供应商)上安装此服务,并且它可以按预期工作。如果有人能给我任何建议,我将不胜感激。我怀疑这个设备出于某种原因会终止服务,但从未调用过 onDestroy。会不会是别的?

受影响的设备是 X96 Amlogic S905X 四核 Android 6.0 电视盒(链接:https://www.alibaba.com/product-detail/X96-Amlogic-S905X-Quad-Core-Android_60599604444.html?s=p

谢谢。

编辑:可能的重复/答案不相关,我可以很好地捕捉连接超时并增加连接超时:

 client.setConnectTimeout(10, TimeUnit.MINUTES);

没用。

但是,我有一些新信息:我尝试向使用 UDP 的服务添加一些其他功能,但我遇到了同样的问题。服务正常工作 10 分钟,但随后我不断收到:

java.net.SocketException: sendto failed: EPERM (Operation not permitted)

我想它在某种程度上相关?任何帮助将非常感激。

【问题讨论】:

  • 每个 STB 的 Android 操作系统版本 (API) 是什么?
  • @HarshSharma 谢谢,但我可以很好地捕捉到该异常。我的问题是,即使我们的服务器在线,我也会遇到该异常。 (只有在服务器关闭时才应该抛出)
  • @Alexandre 有问题的设备是 Android 23 (6.0),可以工作的设备是 Android 22 (5.1.1)
  • @Kubik 您在应用程序类中初始化改造客户端时是否尝试过类似的操作,或者如果您没有尝试过,请尝试一下 [[ OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(10, TimeUnit.MINUTES) .writeTimeout(10, TimeUnit.MINUTES) .readTimeout(10, TimeUnit.MINUTES); OkHttpClient 客户端 = builder.build(); ]]

标签: java android udp retrofit2 television


【解决方案1】:

受影响设备(X96 Amlogic S905X 四核 Android 6.0 电视盒)的解决方案是在 Android Manifest 中添加至少一项活动。该活动从未向用户显示,但它以某种方式解决了这个问题。

(服务从接收器启动,带有 android.intent.action.BOOT_COMPLETED 的意图过滤器)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 2020-09-18
    • 2014-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多