0

我正在制作一个 android 应用程序,它需要它从远程服务器获取一些信息,因此我必须在异步任务中发出一个 http 请求。现在的问题是响应有时需要超过 2 秒的时间,并且当它完成时给出http超时异常,但大多数时候它工作得很好。所以我想实现当我收到http超时异常时我想再次重试请求的功能(再次尝试doinBackground,因为网络调用只能在主线程以外的线程),因为它很可能会成功,并且所有需要从远程服务器获取的东西都将发生在CallRemoteServer()方法中

现在在我的程序中我已经实现了这样的东西

new AsyncTask<Void, Void, Void>() {
private boolean httpResponseOK = true; 
            @Override
            protected Void doInBackground(Void... params) {
                try {

                CallRemoteServer();
                }

                } catch (Exception e) {
                    httpResponseOK = false;
                    e.printStackTrace();
                }

                return null;
            }

            @Override
            protected void onPostExecute(Void result) {

                if (httpResponseOK == false) {

        //Show an alert dialog stating that unable to coonect
                                        }
else
{
     //update UI with the information fetched
}
                                    }); 

有人可以建议我如何实现我上面提到的某些东西,我的意思是,如果我得到除了超时以外的其他异常而不是显示警报对话框,否则在显示无法连接的对话框之前重试至少五次 CallRemoteServer 方法。

我想不出任何好的方法来实现这个逻辑。

提前致谢

4

1 回答 1

1

你可能会得到一个ConnectTimeoutException(或在日志中检查IOException你得到了什么)。我会首先尝试延长超时。可以在此处此处找到一些类似的答案。

但是,必须具有自动重新连接机制。我会使用递归代码来实现它:

final int maxAttempts = 5;
protected MyServerData callRemoteServer(int attempt) throws IOException {
    try {
        // do the IO stuff and in case of success return some data
    } catch (ConnectTimeoutException ex) {
        if(attempt == maxAttempts) {
            return callRemoteServer(attempt + 1);
        } else {
            throw ex;
        }
    }
}

您的doInBackground方法应如下所示:

@Override
protected Void doInBackground(Void... params) {
    try {

        callRemoteServer(0);
    }

    catch (Exception e) {
        e.printStackTrace();
    }

    return null;

}

这样,如果连接超时,它将尝试重试最多 5 次(您可以将最大尝试设置为您喜欢的任何内容)。只要确保从这个 IO 操作返回一些数据,因为无论如何这是该方法最有价值的资产......

出于这个原因,我会将其更改为以下内容:

private class MyAsynckTask extends AsyncTask<Void, Void, MyServerData> {

    @Override
    protected MyServerData doInBackground(Void... params) {
        try {

            return callRemoteServer(0);
        }

        catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    @Override
    protected void onPostExecute(MyServerData result) {
        if(result != null) {
            // display data on UI
        }
    }
}
于 2013-07-31T07:10:35.230 回答