开发者

Android: ServerSocket.accept() randomly freezes

I have a WebView that is fed from a background thread via a ServerSocket on localhost. This works very well, but sometimes the background thread randomly stops accepting requests ("Web page not available"). After some time, it works again without any changes, th开发者_JS百科at is, without restarting the thread or the socket or calling accept() again.

EDIT 2: Further investigation showed that WebView seems to have a (separate?) timeout value for localhost connections that is so small that sometimes the server thread doesn't get a chance to handle the request. As a workaround, I can reload the page when WebClient.onReceivedError is invoked, which eventually loads the page. Anyone having the same problem?

When I open the debugger, I can see that the server thread is still running properly and is waiting (blocked) in the ServerSocket.accept() method (or, more precisely, in OSNetworkSystem.accept(...)). However, accept() doesn't seem to receive the incoming request.

There is is nothing special in my code:

ServerSocket serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(0);

while (!shutdown) {
    Socket socket = null;
    try {
        socket = serverSocket.accept();
        // Parse request and create response
    } catch (Exception e) {
        // ...
    } finally {
        // ... close socket
    }
}

I use the same code on Windows/Mac and have never experienced any such problems.

This seems to me like a bug in Android, perhaps related to power management optimizations. Any clues?

EDIT: The problem does not occur on Android 2.x, only on Android 3.1 (Samsung Galaxy Tab 10.1).


This problem is a bug in Android.

I have filed a bug report under http://code.google.com/p/android/issues/detail?id=19427

EDIT: As a workaround, I added some code to reload the page whenever a connection error occurs. This has worked quite well so far.

webView.setWebViewClient(new WebViewClient(){
    String prevFailingUrl;
    int retryCount;
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        if (errorCode == WebViewClient.ERROR_CONNECT) {
            if (failingUrl.equals(prevFailingUrl)) {
                retryCount++;
            } else {
                retryCount = 1;
            }
            if (retryCount <= 3) {
                webView.reload();
            }
        }
        prevFailingUrl = failingUrl;
    }
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜