在我的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,所以如果你注意到任何低效的代码,请告诉我。
答案 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();
}
});