Bis zum 15.2.2012 habe ich noch keine gute Erklärung und keinen Grund gefunden, warum dies nicht funktioniert. Am nächsten an einer Lösung ist die Verwendung des traditionellen Thread- Ansatzes. Warum sollte dann eine Klasse in das Android SDK aufgenommen werden, die (anscheinend) nicht funktioniert?
Evenin 'SO!
Ich habe eine AsyncTask-Unterklasse:
// 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
Das wird so ausgeführt:
xmlAsync xmlThread = new xmlAsync();
xmlThread.execute("http://www.nothing.com");
Jetzt ist diese Unterklasse auf einen kleinen Fehler gestoßen. Früher wurde XML-Analyse durchgeführt, aber als ich bemerkte, dass doInBackground () nicht aufgerufen wurde, habe ich es Zeile für Zeile entfernt und schließlich genau das erreicht:
@Override
protected Void doInBackground(String... params)
{
Log.v(TAG, "doInBackground");
return null;
}
Was aus irgendeinem Grund nichts protokollierte. Ich habe jedoch Folgendes hinzugefügt:
@Override
protected void onPreExecute()
{
Log.v(TAG, "onPreExecute");
super.onPreExecute();
}
Und diese Zeile wird tatsächlich beim Ausführen des Threads protokolliert. Also wird onPreExecute () irgendwie aufgerufen, aber nicht doInBackground () . Ich habe eine andere AsyncTask, die gleichzeitig im Hintergrund läuft, was gut funktioniert.
Ich verwende die App derzeit auf einem Emulator, SDK Version 15, Eclipse, Mac OS X 10.7.2, in der Nähe des Nordpols.
BEARBEITEN:
@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 () fügt einer SQLiteDatabase mehr oder weniger eine Zeile hinzu, die mit dem Kontext der Aktivität initialisiert wird. PublishProgress () wird vom Rückruf des Interface ParseListener aufgerufen. Da ich jedoch in doInBackground () nur log.v mache, fand ich dies zunächst unnötig, um es überhaupt aufzurufen.
EDIT 2:
Okay, um ganz klar zu sein, dies ist die andere AsyncTask, die in derselben Aktivität ausgeführt wird und einwandfrei funktioniert.
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();
}
}
EDIT 3:
Seufz, tut mir leid, dass ich schlecht darin bin, Fragen zu stellen. Aber hier ist die Initialisierung der Aufgaben.
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);
}