Aller au contenu

Comment insérer un objet de type List<String>


deep21

Recommended Posts

Bonjour,

J'essaye d'envoyer du contenu xml à mon main activity qui a été soigneusement traité via une classe en utilisant SaxParser.

Dans mon Thread ma méthode sax.getListXml() me renvoie un objet listXml de type List<String>.

J'essaye de trouver une solution pour envoyer à mon handler les données que me renvoie la méthode getListXml()

Pour faire plus simple dois-je serialiser arrayAdapter ou bien sérialiser getListXml()?

Voici le code:

@Override
protected void onstart() {
super.onstart();
new Thread(new Runnable() {
public void run() {
SaxPArser sax = new SaxPArser();
sax.documentParser("http://uni111.ogame.fr/api/players.xml");
Message msg = handler.obtainMessage();
bundle = new Bundle();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
getApplicationContext(), 0, sax.getListXml());
bundle.put()
msg.setData(bundle);
handler.sendMessage(msg);
}
}).start();
}

Lien vers le commentaire
Partager sur d’autres sites

Je reviens vers vous, car j'ai réussi à afficher les résultats xml dans la listView.

Voici le code

package com.example.listviewtest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
protected ProgressDialog mProgressDialog;
private ListView listView;
private Bundle bundle;
private Handler handler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
  ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
 getApplicationContext(), android.R.layout.simple_list_item_1,
  msg.getData().getStringArrayList("key"));
  listView.setAdapter(arrayAdapter);

 }
};
@Override
public void onCreate(Bundle savedInstanceState) {
 Log.d(null, "onCreate");
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 listView = (ListView) findViewById(R.id.listView1);
}
@Override
protected void onstart() {
 super.onstart();
 new Thread(new Runnable() {
  public void run() {
   SaxPArser sax = new SaxPArser();
   sax.documentParser("http://uni111.ogame.fr/api/players.xml");
   Message msg = handler.obtainMessage();
   bundle = new Bundle();
   bundle.putStringArrayList("key", sax.getListXml());
   msg.setData(bundle);
   handler.sendMessage(msg);
  }
 }).start();
}
}

Je voudrais savoir si la manière dont je me suis pris pour arriver à afficher les résultats dans le UI est la bonne.

Je vous serai très reconnaissant si vous pouviez me donner des conseils, des méthodes ...

Cordialement

Lien vers le commentaire
Partager sur d’autres sites

Je crois que t'aurai pu bêtement déclarer ta variable dans ta classe en final et l'utiliser dans le thread puis prévenir qu'elle est rempli avec l'event vu que t'es dans la même classe.

Mais ta manière est bonne :)

Si t’utilises ton bundle qu'à un seul endroit ne le déclare pas dans la classe.

PS: N'ai pas peur d'espacer ton code c'est plus simple à lire et de toute façon une fois transformé en code machine la mise en forme change rien.

Edit:

Comme t'es parti tu devrais peut être créer carrément une classe pour ton thread, tu lui envoies en argument ton handler et le nom de ton fichier xml et ça te fait une jolie classe réutilisable lecteur de stream xml.

Faut pas hésiter non plus sur le nombre de fichiers, plus un code est clair plus il sera facilement débuggable et puis la programmation objet c'est notre but :)

Normalement on sépare ce qui gère l'ui du reste, pour plein de raison, donc en déplaçant ton thread dans une classe tu te conformes à une règle d'un bon programmeur :D

Dans ta classe principale tu gèrera l'ui et dans une classe séparé le chargement du xml.

Dans une classe runnable si tu veux lui passer des variables tu peux facilement dans le constructeur.

Lien vers le commentaire
Partager sur d’autres sites

Salut,

Merci pour ces commentaires intéréssant et cela m'aidera de mettre le pied à l'étrier.

Je crois que t'aurai pu bêtement déclarer ta variable dans ta classe en final et l'utiliser dans le thread puis prévenir qu'elle est rempli avec l'event vu que t'es dans la même classe

Excuse moi, mais je ne te suis pas, tu parles de quelle variable?

Est ce que tu pourrais détailler un peu plus s'il te plait?

Lien vers le commentaire
Partager sur d’autres sites

Je crois que j'ai dit des conneries ... il était tard et me suis emballé, je finis mon test pour être sur ...

J'ai dit une connerie sur le final mais j'avais pas faux sur la variable dans la classe, regardes mon projet test :

package com.example.listviewtest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {
protected ProgressDialog mProgressDialog;
private ListView listView;
private ArrayList<Data> data;


private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
loadDataInList();
}
};

@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(null, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
}

@Override
protected void onstart() {
super.onstart();

new Thread(new Runnable() {
public void run() {
data = _parseXml();

Message msg = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putBoolean("key", true);
msg.setData(bundle);
handler.sendMessage(msg);
}
}).start();
}

private void loadDataInList() {
ArrayList<HashMap<String, String>> listItem = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map;

for (Data item : data) {
map = new HashMap<String, String>();
map.put("name", item.name);
map.put("id", item.id);
map.put("status", item.status);
map.put("alliance", item.alliance);
listItem.add(map);
}

SimpleAdapter m_adapter = new SimpleAdapter (this.getBaseContext(), listItem, R.layout.list_item,
		 new String[] {"name", "id", "status", "alliance"}, new int[] {R.id.name, R.id.id, R.id.status, R.id.alliance});

listView.setAdapter(m_adapter);
}

private ArrayList<Data> _parseXml() {
ArrayList<Data> data = null;

// sax stuff
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();

XMLReader xr = sp.getXMLReader();

DataHandler dataHandler = new DataHandler();
xr.setContentHandler(dataHandler);

DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpPost post = new HttpPost("http://uni111.ogame.fr/api/players.xml");

 HttpResponse res = httpClient.execute(post);
 HttpEntity entity = res.getEntity();


xr.parse(new InputSource(entity.getContent()));

data = dataHandler.getData();

} catch (ParserConfigurationException pce) {
Log.e("SAX XML", "sax parse error", pce);
} catch (SAXException se) {
Log.e("SAX XML", "sax error", se);
} catch (IOException ioe) {
Log.e("SAX XML", "sax parse io error", ioe);
}

return data;
}
}

Et je te passe le projet complet c'est plus simple pour regarder : http://db.tt/CHW56I8C

J'ai fait ça vite fait pour me mettre dans tes conditions :)

Edit: Il y a des lettres qui changent dans la visualisation de code sur le fofo, des majuscules passent en minuscules comme sur le onstart ... ça sent la protection javascript ^^

Lien vers le commentaire
Partager sur d’autres sites

Merci d'avoir pris le temps de refaire ce projet, vraiment très gentil.

J'aimerai avoir quelques informations sur la façon dont tu y es pris pour structurer le code.

1-) Dans ta classe DataHandler, pourquoi les variables _data,_inSection commencent par un _ ainsi que ta méthode _parseXml() dans le MainActivity?

2-) Pourquoi tu as crée une classe Data, est ce que c'est pour récupérer les données sous formes d'objets qui te permetra justement de faire le pont avec la classe DataHandler?

3-) Dans ta DataHandler Pourquoi préfère tu instancier l'objet _data à la lecture du fichier xml?

4-)

Message msg = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putBoolean("key", true);
msg.setData(bundle);
handler.sendMessage(msg);

Tu créer un Bundle, tu lui envoi un boolean en liant ce dernier avec une clé, et dans la fonction HandleMessage a aucun moment tu ne récupères le msg.

Je pensais que c'est dans le corps du msg qu'on pouvais envoyer des données via un Bundle et le récupérer dans HandleMessage.

Peux tu éclairer ma lanterne stp.

Lien vers le commentaire
Partager sur d’autres sites

Ben d'abord pour les noms de variables avec underscore c'est parce que j'ai fait du copié/collé d'un exemple trouvé sur le net ^^

J'ai fait ce mini projet juste pour te montrer que ta liste vu que t'étais dans la même classe tu pouvais la charger sans le bundle, mais en tant normal on lui passe mini un int pour identifier la fonction l'appelant.

Là le booléen que je lui passe sert à rien ^^

La classe Data est un objet perso, que pour que tu comprennes bien j'aurai du appeler Player. Elle représente un objet Player avec ces 4 valeurs, ça me permet de créer une array de player que je remplis avec sax.

Pour remplir ma listview avec layout perso ça me donne un accès facile aux différentes données d'un player.

Je me sert du handler que pour savoir quand j'ai finis de récupérer ma liste de joueur.

Je crois avoir tout répondu, mais j'ai fais ça vite fait, Il y a même peut etre des erreurs mais ça fonctionne et j'ai un peu compliqué la liste en créant une liste d'objet perso car c'est encore plus dur à faire passer dans un bundle et bien plus pratique à l'utilisation.

Puis je voyais pas ce que t'avais fait avec les 4 valeurs pour en faire un string :P

Edit: Et une array on peut la trier, accéder à un objet avec une seule valeur, ...

Edit2:

Ah j'ai oublié la question 3 je crois, à vrai dire c'était l'exemple qui était fait comme ça mais tu voudrais l'instancier où ? Vu qu'elle sert à stocker le xml elle ne sert à rien tant qu'on ne l'a pas ouvert.

J'ai jamais utilisé saxparser du coup je me suis appuyé sur ce tuto : http://www.jondev.net/articles/Android_XML_SAX_Parser_Example

Mais je comptais pas t'expliquer ou te montrer quoi que ce soit là dessus, on en parlait même pas, ce que je voulais te montrer c'était l'utilisation de la variable sans la faire passer par l'handler et l'objet perso data avec l'adapter custom sur la listview au cas où tu connaissais pas.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...