截至2012年2月15日,我还没有找到一个好的解释或原因来说明为什么这不能工作。最接近解决方案的是使用传统的线程方法,但是为什么在Android SDK中包含一个看起来不能工作的类呢?
晚上好,SO!
我有一个AsyncTask子类:
// ParseListener had a callback which was called when an item was parsed in a
// RSS-xml, but as stated further down it is not used at all right now.
private class xmlAsync extends AsyncTask<String, RSSItem, Void> implements ParseListener
这样执行:
xmlAsync xmlThread = new xmlAsync();
xmlThread.execute("http://www.nothing.com");
现在这个子类遇到了一个小错误。之前它进行了一些XML解析,但当我注意到它的doInBackground()没有被调用时,我逐行削减代码,最终只保留以下内容:
@Override
protected Void doInBackground(String... params)
{
Log.v(TAG, "doInBackground");
return null;
}
出于某种原因,它没有记录任何内容。不过,我添加了这个:
@Override
protected void onPreExecute()
{
Log.v(TAG, "onPreExecute");
super.onPreExecute();
}
在执行线程时确实记录了那行代码。所以某种方式调用了onPreExecute()但没有调用doInBackground()。我同时在后台运行另一个异步任务,它可以正常工作。
我目前在模拟器上运行此应用程序,SDK版本为15,使用Eclipse和Mac OS X 10.7.2,距离北极非常近。
编辑:
@Override
protected void onProgressUpdate(RSSItem... values) {
if(values[0] == null)
{
// activity function which merely creates a dialog
showInputError();
}
else
{
Log.v(TAG, "adding "+values[0].toString());
_tableManager.addRSSItem(values[0]);
}
super.onProgressUpdate(values);
}
_tableManager.addRSSItem()函数会向SQLiteDatabase添加一行数据,并使用该活动的上下文进行初始化。publishProgress()由接口ParseListener的回调函数调用。然而,由于在doInBackground()中我仅做log.v操作,因此我认为这个功能不必要。
编辑2:好的,为了更加清楚,这是另一个AsyncTask,在同一个活动中执行并正常工作。private class dbAsync extends AsyncTask<Void, RSSItem, Void>
{
Integer prevCount;
boolean run;
@Override
protected void onPreExecute() {
run = true;
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
run = true;
prevCount = 0;
while(run)
{
ArrayList<RSSItem> items = _tableManager.getAllItems();
if(items != null)
{
if(items.size() > prevCount)
{
Log.v("db Thread", "Found new item(s)!");
prevCount = items.size();
RSSItem[] itemsArray = new RSSItem[items.size()];
publishProgress(items.toArray(itemsArray));
}
}
SystemClock.sleep(5000);
}
return null;
}
@Override
protected void onProgressUpdate(RSSItem... values) {
ArrayList<RSSItem> list = new ArrayList<RSSItem>();
for(int i = 0; i < values.length; i++)
{
list.add(i, values[i]);
}
setItemsAndUpdateList(list);
super.onProgressUpdate(values);
}
@Override
protected void onCancelled() {
run = false;
super.onCancelled();
}
}
编辑3:
叹气,抱歉我不太擅长提问。以下是Tasks的初始化:
xmlAsync _xmlParseThread;
dbAsync _dbLookup;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_dbLookup = new dbAsync();
_dbLookup.execute();
_xmlParseThread = new xmlAsync();
_xmlParseThread.execute("http://www.nothing.com", null);
}
doInBackground
中的登录未显示时,我真的很惊讶。我也有一个活动和两个AsyncTask。第一个任务(文件下载)阻塞了第二个任务(使用来自数据库的数据更新UI)。 - S.Thiongane