异步任务错误处理

16

我正在使用AsyncTask来执行一些后台计算,但我无法找到正确的方式来处理异常。目前我正在使用以下代码:

private class MyTask extends AsyncTask<String, Void, String>
{
    private int e = 0;

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            URL url = new URL("http://www.example.com/");
        }
        catch (MalformedURLException e)
        {
            e = 1;
        }

        // Other code here...

        return null;
    }

    @Override
    protected void onPostExecute(String result)
    {
        if (e == 1)
            Log.i("Some Tag", "An error occurred.");

        // Perform post processing here...
    }
}

我认为变量e可能会被主线程和工作线程同时写入/访问。因为我知道onPostExecute()只有在doInBackground()完成后才会运行,所以我可以省略任何同步吗?

这是不好的代码吗?在AsyncTask中处理异常是否有一种公认或正确的方式?


1
可能是Android上的AsyncTask和错误处理的重复问题。 - blahdiblah
3个回答

3

我一直在我的应用程序中这样做,我想没有更好的方法。

您还可以阅读Mark Murphy的答案


如果它没有引起问题,那我就很高兴! - Leo

3
我认为你的代码可以胜任任务,但是AsyncTask类中已经内置了某种形式的错误处理。
你可以通过使用cancel()方法及其处理程序方法onCancelled(),避免使用额外变量。当你在doInBackground()方法中调用cancel时,将在UI线程中调用onCancelled方法。无论你调用cancel(true)还是cancel(false),都取决于你的需求。
private class MyTask extends AsyncTask<String, Void, String>
{    
    @Override
    protected NewsItem doInBackground(String... params)
    {
        try
        {
            URL url = new URL("http://www.example.com/");
        }
        catch (MalformedURLException e)
        {
            cancel(false/true);  
        }

        // Other code here...

        return null;
    }

    @Override
    protected void onPostExecute(String result)
    {              
        // Perform successful post processing here...
    }

   @Override
    protected void onCancelled() {
        super.onCancelled();
        // Perform error post processing here...
    }
}

这种方法仅适用于我们只有一种类型的异常。在我的完整代码中,可能会出现多种问题,它们必须以不同的方式进行处理。 - Leo
为什么?您可以在try块中添加任意数量的catch块。在每个catch语句中,您都可以调用cancel方法。您还可以使用catch(Exception e)来捕获所有类型的异常。我理解得对吗,Leo?然而,当抛出异常时调用cancel()是否是良好的实践,或者是否有其他实现异常处理的方式? - OneWorld
处理错误的cancel()方法非常接近实际情况。由于出现错误,您的处理已被取消。您仍然可以在ASyncTask上保存一些状态,以便UI线程读取并获取有关错误的更多信息。 - DukeMe

2

即使在SMP架构下,这也是保证可行的。所有同步操作都已经为您完成。然而,最好使用返回值来执行此操作。


1
在实际代码中,我使用了一个自定义对象作为返回类型,这并不适合保存异常信息。我猜我不能很容易地重载 onPostExecute() 函数? - Leo
4
首先,doInBackground必须返回与onPostExecute()参数相同类型的对象。然后你可以创建一个自定义类来封装结果和异常:class ResultHolder { Exception e; MyResult r; } - Romain Guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接