在AsyncTask Android中显示Toast时出错

时间:2014-04-11 05:24:30

标签: android android-asynctask toast

在我的RSS阅读器应用程序中,我正在尝试检查输入RSS网址是否有效。如果是这样,我将它保存在SQLite数据库中。我的方法是使用AsyncTask:

class mAsyncTask extends AsyncTask<String, Integer, String>
{
    private boolean succeed = false;

    public mAsyncTask()
    {
    }

    protected String doInBackground(String... urls)
    {
        try
        {
            URL sourceUrl = new URL(sourceUrlString);

            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(false);
            XmlPullParser xpp = factory.newPullParser();

            // We will get the XML from an input stream
            xpp.setInput(global.getInputStream(sourceUrl), "UTF_8");

            // if it reach here, it means the XML is in a valid
            // format
            if (xpp.getEventType() == XmlPullParser.START_TAG)
            {
                if (xpp.getName().equalsIgnoreCase("title"))
                    sourceTitle = xpp.nextText();
                succeed = true;
            }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "Input RSS feed is not in the valid format...", Toast.LENGTH_LONG).show();
        }
        catch (XmlPullParserException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            Toast.makeText(getApplicationContext(), "Unknown error occurred..", Toast.LENGTH_LONG).show();
        }

        return "Complete doInBackground";
    }

    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... progress)
    {
        super.onProgressUpdate(progress);
    }

    @Override
    protected void onPostExecute(String result)
    {
        super.onPostExecute(result);

        if (succeed == true)
        {
            db.addSource(new Sources("", sourceTitle, sourceUrlString));

                            //refresh
            Intent intent = getIntent();
            finish();
            startActivity(intent);
        }
    }
}

sourceUrlString是来自AlertDialog的输入字符串。 db是数据库处理程序类。 Sources构造函数包含3个变量:feed的类别,标题和url,所有这些都是String。

基于LogCat,每次尝试在catchs内显示Toast时都会收到错误。知道为什么吗?

另外,这是我第一次尝试实现AsyncTask,所以如果你注意到任何低效的代码,请告诉我。

7 个答案:

答案 0 :(得分:2)

试试这个..

您无法在Toast中显示doInbackground。所以试试如下。

doInBackground返回字符串中,如下所示。

protected String doInBackground(String... urls)
{
    try
    {
        URL sourceUrl = new URL(sourceUrlString);

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        XmlPullParser xpp = factory.newPullParser();

        // We will get the XML from an input stream
        xpp.setInput(global.getInputStream(sourceUrl), "UTF_8");

        // if it reach here, it means the XML is in a valid
        // format
        if (xpp.getEventType() == XmlPullParser.START_TAG)
        {
            if (xpp.getName().equalsIgnoreCase("title"))
                sourceTitle = xpp.nextText();
            succeed = true;
        }
    }
    catch (MalformedURLException e)
    {
        return "MalformedURLException";
        e.printStackTrace();        }
    catch (XmlPullParserException e)
    {
        return "XmlPullParserException";
        e.printStackTrace();
    }
    catch (IOException e)
    {
        return "IOException";
        e.printStackTrace();
    }
    catch (Exception e)
    {
        return "Exception";            
    }

    return "Complete doInBackground";
}

onPostExecute中进行检查,如下所示,并显示Toast

@Override
protected void onPostExecute(String result)
{
    super.onPostExecute(result);

    if(result.equals("Exception"))
    {
       Toast.makeText(getApplicationContext(), "Unknown error occurred..", Toast.LENGTH_LONG).show();
    }else if(result.equals("IOException"))
    {
       Toast.makeText(getApplicationContext(), "IOException..", Toast.LENGTH_LONG).show();
    }else if(result.equals("XmlPullParserException"))
    {
       Toast.makeText(getApplicationContext(), "XmlPullParserException..", Toast.LENGTH_LONG).show();
    }else if(result.equals("MalformedURLException"))
    {
       Toast.makeText(getApplicationContext(), "MalformedURLException..", Toast.LENGTH_LONG).show();
    }else{


    if(succeed)
    {
        db.addSource(new Sources("", sourceTitle, sourceUrlString));

                        //refresh
        Intent intent = getIntent();
        finish();
        startActivity(intent);
    }
    }
}

答案 1 :(得分:2)

UI始终在单独的线程中运行,您无法从其他线程更改UI。使用Handler从后台线程更新UI。

               handler = new Handler();
                handler.post(new Runnable() {

                @Override

                public void run() {

                   Toast.makeText(getApplicationContext(), "Unknown error occurred..",       Toast.LENGTH_LONG).show();

                }
         });

答案 2 :(得分:1)

doInBackground()方法在其单独的Thread中运行。它不允许与UIThread进行交互。您希望显示实际上是要处理的UIThread功能的Toast消息。

只要您的控件位于工作线程中,就无法更新UI。对于AsyncTask类onPreExecute()&amp; onProgressUpdate()只有这两种方法允许在UIThread上执行时与UI进行交互。

答案 3 :(得分:0)

你应该在UI线程上调用Toast。

答案 4 :(得分:0)

由于doInBackGround在单独的线程上运行,因此无法从那里显示toast意味着更新UI。但是你可以从onPreExecute,onPostExecute和onProgressUpdate更新UI,因为它们在主线程上运行。因此,您可以使用这些方法来更新UI。

所以你可以发布进程调用onProgressUpdate来显示toast,或者只是将一些值返回给onPostexecute并根据那个show toast ..

答案 5 :(得分:0)

应该在UI线程上调用Toast。如果你想在doBackground()中显示toast,你可以使用runOnUiThread();

来实现它
catch (Exception e)
{
        YourActivity.this.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), "Unknown error occurred..", Toast.LENGTH_LONG).show();
        }
     }
});

答案 6 :(得分:0)

通过runOnUiThread()实现此目的。 Asynctask在单独的线程中运行,因此您无法从doInBackground()更新UI。

getActivity().runOnUiThread(new Runnable() {
  @Override
  public void run() {
    Toast.makeText(getApplicationContext(), "Unknown error occurred..", Toast.LENGTH_LONG).show();
  }
});