我如何在doinBackground()方法中处理特殊类型的异常

时间:2013-07-31 06:47:21

标签: android exception-handling android-asynctask

我正在制作一个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方法连接。

我无法想到实现这种逻辑的任何好方法。

提前致谢

1 个答案:

答案 0 :(得分:1)

您可能正在获得ConnectTimeoutException(或在日志中查看您获得的IOException是什么)。我会先尝试延长超时时间。可以找到一些类似的答案herehere

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

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
        }
    }
}