【问题标题】:How can i Handle special kind of exception in doinBackground() method我如何在 doinBackground() 方法中处理特殊类型的异常
【发布时间】:2013-07-31 06:47:20
【问题描述】:

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

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

提前致谢

【问题讨论】:

  • doInBackground() 方法中,捕获错误并设置一个标志,该标志将被发送回Activity,从那里您调用AsyncTask。如果设置了标志 - 然后重试AsyncClass.execute()
  • 没有什么可以阻止您在doInBackgroundAsyncTask 方法中循环。只需使用int 来计算循环并设置boolean 以检查while 循环。如果 int 超过 4 或 boolean 设置为 true(对于成功的结果),则应退出 while 循环。
  • @Squonk 如果我使用 while 循环和简单的计数器逻辑,那么一旦我遇到异常,它将退出并转到 catch(Exception e) 行

标签: android exception-handling android-asynctask


【解决方案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
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    相关资源
    最近更新 更多