HttpURLConnection,打开/关闭 WiFi 并尝试连接时出现问题

发布于 2024-10-30 17:37:07 字数 2084 浏览 1 评论 0原文

我有一个应用程序是 RESTful API 使用者,我希望与 API 的连接超时。

正如我所搜索和测试的那样, HttpURLConnection.setReadTimeout() 方法不起作用,因此我找到的解决方案是使用 AsyncTask ,它将尝试连接到服务器,然后将超时传递给 AsyncTask.get ()。

它是部分有效的。问题是当我执行以下操作时:

  • 在打开 WiFi 的情况下进入应用程序。我单击“登录”按钮并收到“无效/用户密码”。好的。
  • 关闭WiFi,点击“登录”按钮。应用程序尝试连接,但 5 秒(我选择的超时时间)后,它向我显示通知对话框,提示我未连接。好吧,一切都如预想的那样。
  • 重新打开 WiFi,单击“登录”按钮。它仍然工作,就好像我没有连接一样,总是显示对话框。我可以等待很多秒,但行为与断开连接时的行为相同。

我使用 Eclipse 一步步调试了我的所有代码,逻辑上没有任何问题。 我的 HttpURLConnection 始终是一个新对象,因此我不会尝试在重新打开 WiFi 后使用相同的连接对象进行连接... 另外,我正在使用 Scribe 库进行 OAuth,但我检查了源代码,一切似乎好的,除了我更改了创建连接的方法以始终使用新实例。

我开始认为 Android 正在“缓存”我的连接对象或 AsyncTask 对象...

在我的 RequestManager 类的一些代码下面:

public class RequestManager {
    private static RequestManager self = new RequestManager(); 
    private Request currentRequest;

    private static final long TIMEOUT = 5000;

    public static RequestManager getInstance() {
        return self;
    }

    public void startRequest(Request request) {
        if (currentRequest != null) return;
        currentRequest = request;
    }

    public String getResponse() throws ConnectionErrorException {
        RequestThreat rt = new RequestThread();
        rt.execute(currentRequest);  
        try {
            return (String) rt.get(TIMEOUT, TimeUnit.MILISECONDS);
        } catch (InterruptedException e) {
        } catch (ExecutionException e) {
        } catch (TimeoutException e) {
            throw new ConnectionErrorException();
        } finally {
            endRequest();
        }
        return null;
    }

    public void endRequest() {
        currentRequest = null;
    }

    private class RequestThread extends AsyncTask<Request, Integer, String> {
        @Override
        protected String doInBackground(Request... requestParams) {
            return requestParams[0].send().getBody();
        }
    }

}

也在我调用的方法中调用 getResponse() endRequest() 之后。

有什么想法吗?

I have an application which is a RESTful API consumer, and I wish to have a timeout on my connection with the API.

As I've searched, and also tested, the HttpURLConnection.setReadTimeout() method doesn't work, so the solution I found was to use an AsyncTask which will try to connect to the server and then pass the timeout to the AsyncTask.get().

It works, partially. The problem is when I do the following:

  • Enter the application with the WiFi turned on. I click "Login" button and get "Invalid/User password". Ok.
  • Turn off the WiFi, click "Login" button. The application tries to connect but after 5 seconds (the timeout I chose) it shows me the notification dialog saying I'm not connected. Ok, everything as expected.
  • Turn on back the WiFi, click "Login" button. It stills working as if I was not connected, always showing the dialog. I can wait many seconds but the behaviour is the same as If I was disconnected.

I debugged all my code, step by step using Eclipse and there's nothing wrong with the logic.
My HttpURLConnection is always a new object, so I'm not trying to use the same connection object to connect after the WiFi is turned on back...
Also I'm using the Scribe library, for OAuth, but I checked the source code and everything seems ok, except that I changed the method which creates a connection to always use a new instance.

I'm starting to think that Android is "caching" my connection object or the AsyncTask object...

Below some code of my RequestManager class:

public class RequestManager {
    private static RequestManager self = new RequestManager(); 
    private Request currentRequest;

    private static final long TIMEOUT = 5000;

    public static RequestManager getInstance() {
        return self;
    }

    public void startRequest(Request request) {
        if (currentRequest != null) return;
        currentRequest = request;
    }

    public String getResponse() throws ConnectionErrorException {
        RequestThreat rt = new RequestThread();
        rt.execute(currentRequest);  
        try {
            return (String) rt.get(TIMEOUT, TimeUnit.MILISECONDS);
        } catch (InterruptedException e) {
        } catch (ExecutionException e) {
        } catch (TimeoutException e) {
            throw new ConnectionErrorException();
        } finally {
            endRequest();
        }
        return null;
    }

    public void endRequest() {
        currentRequest = null;
    }

    private class RequestThread extends AsyncTask<Request, Integer, String> {
        @Override
        protected String doInBackground(Request... requestParams) {
            return requestParams[0].send().getBody();
        }
    }

}

Also in the method I call getResponse() I'm calling endRequest() after.

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坦然微笑 2024-11-06 17:37:07

在尝试访问网络之前,您应该检查网络连接是否可用。看看这个问题:

具体来说:

NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()) {

You should check to see if a network connection is available before trying to access the network. Have a look at this quesion:

Specifically:

NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()) {
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文