Comment obtenir XML à l'aide de AsyncTask et la Minuterie?
Afin d'obtenir des données XML à partir d'un serveur à plusieurs reprises, je suis d'essayer d'utiliser AsyncTask et Minuterie comme par Mark Murphy suggestion.
J'obtiens l'erreur suivante:
01-07 16:11:26.705: ERROR/AndroidRuntime(729):
Caused by: java.lang.RuntimeException:
Can't create handler inside thread that has not
called Looper.prepare()
Je suis en utilisant le SDK 1.5 avec Eclipse sous Windows.
J'ai regardé dans la documentation, sur StackOverflow et les Développeurs Android de groupe, mais je ne suis pas clair quelle est la cause de l'erreur ou comment résoudre le problème.
Je peux obtenir les données une seule fois -- c'est à dire sans Async et Minuterie -- et l'analyse par SAX sans problèmes.
Complète le code de l'application ci-dessous.
S'il vous plaît excusez toutes les naïfs erreurs: je suis assez nouveau pour Android.
package com.foo.bar.myactivity;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Timer timer;
timer = new Timer();
timer.schedule(new MyTimerTask(), 0, 1000);
}
public class MyAsyncTask extends AsyncTask<String, Integer, MyData> {
protected MyData doInBackground(String... string) {
MyData myData = new MyData();
try {
URL url = new URL("http://www.example.com/my.xml");
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
MyHandler myHandler = new MyHandler();
xr.setContentHandler(myHandler);
System.setProperty("http.proxyHost", "www-cache.example.com");
System.setProperty("http.proxyPort", "80");
xr.parse(new InputSource(url.openStream()));
myData = myHandler.getParsedData();
return myData;
} catch (Exception e) {
Log.e(">>>>>>>>>>>> Error getting myData: ", e.getMessage(), e);
return myData;
}
}
protected void onProgressUpdate(Integer... progress) {
//setProgressPercent(progress[0]);
}
protected void onPostExecute(MyData myData) {
Log.d(">>>>>>>>>>>>>My data: ", myData.toString());
}
}
public class MyTimerTask extends TimerTask {
public void run() {
try {
new MyAsyncTask().execute("");
} catch (Exception e) {
Log.e(">>>>>>>>>>>> Error executing MyAsyncTask: ", e.getMessage(), e);
}
}
}
}
OriginalL'auteur Sam Dutton | 2010-01-07
Vous devez vous connecter pour publier un commentaire.
Le problème est dans l'utilisation de TimerTask. TimerTask run devrait poster un gestionnaire, quelque chose comme ceci:
Bien sûr, c'est un peu moche, donc vous recommandons de la classe anonyme.
OriginalL'auteur James
J'ai eu ce travail grâce à James de réponse.
J'ai inclus le code ci-dessous dans le cas où c'est utile à quelqu'un.
Mise en garde développeur! Le code fonctionne pour moi, mais peut contenir des erreurs.
OriginalL'auteur Sam Dutton
Le problème semble être que vous n'avez pas appelé
Looper.prepare()
. Vous pourriez avoir un coup d'oeil à la documentation deLooper
.Un
Gestionnaire
besoin d'une boucle de message pour les messages de processus et un Thread par défaut n'en a pas.Il semble que
AsyncTask
utiliseGestionnaire
en interne donc ajouterLooper.prepare()
en haut de votrerun()
méthode dansMyTimerTask
et qui devrait résoudre votre problème.Sam
MyHandler
ne semble pas être une sous-classe de androidHandler
non???? Sinon, comment il peut être passé comme argument d'uneXmlReader
? Est-il un autre Thread de l'application qui créer unandroid.os.Handler
?Mon erreur, désolé. Le problème est le
AsyncTask
utilise unHandler
de sorte que vous besoin de faire unLooper.prepare()
dans votreTimerTask
fil.Les gars, c'est un SAX gestionnaire de contenu pas un Gestionnaire. :\
Je ne savais pas que dans un premier temps que je n'ai pas lu le code assez attentivement. Comme je l'ai dit ci-dessus, le problème est que
AsyncTask
utilise unHandler
en interne de sorte que vous besoin de créer une boucle de message dans leTimerTask
fil.OriginalL'auteur Dave Webb
J'aimerais utiliser le service avec alarme gestionnaire de
Juste pour rappeler, comme par le commentaire de Dave Webb: j'ai besoin de faire une tâche de fond à plusieurs reprises, pas à un moment précis.
Je pense que mes besoins sont assez clairs: "pour obtenir des données XML à partir d'un serveur à plusieurs reprises" -- et le montre le code que j'ai l'intention d'obtenir des mises à jour à chaque seconde. Je prends votre point que cela peut être fait avec AlarmManager, mais je suis d'accord avec Dave Webb que ce n'est probablement pas la meilleure façon de le faire.
OriginalL'auteur Alex Volovoy
Le problème est que vous ne pouvez pas créer le Gestionnaire d'objet dans le thread qui doInBackground() s'exécute. Je voudrais mettre en œuvre la onPreExecute() la méthode et de mettre votre code d'installation. Essayez de déplacer ces lignes dans le onPreExecute() méthode:
Je pense tout simplement parce qu'il fonctionne sur le thread d'INTERFACE utilisateur qui ne signifie pas que vous devez utiliser uniquement pour les mises à jour de l'INTERFACE utilisateur. À mon avis, faire un peu de configuration rapide dans onPreExecute() ce serait bien.
OriginalL'auteur Mark B