Jump to content

Archived

This topic is now archived and is closed to further replies.

deep21

Mise a jour de l'updatebar depuis un thread

Recommended Posts

Bonjour,

Je vous expose mon problème, je suis entrain de développer une application simple qui permet de télécharger un flux xml à partir d'un lien codé en dur.

Mon application marche et actuellement il m'affiche le contenu xml dans le UI.

Ce que je voudrais réaliser c'est trouver une condition pour ma boucle WHILE qui me permettra de faire progresser mon progressBar pour faire patienter l'utilisateur avant d'afficher le contenu xml dans l'activité.

package com.example.threadhandler;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
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.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity {
protected ProgressDialog mProgressDialog;
private TextView txt;
private ProgressBar bar;
private Bundle bu;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
bu = msg.getData();
txt.setText(txt.getText() + bu.getString("xml"));
bar.incrementProgressBy(10);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(null, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.textView1);
bar = (ProgressBar) findViewById(R.id.progressBar1);
}
@Override
protected void onstart() {
// TODO Auto-generated method stub
Log.d(null, "onstart");
super.onstart();
Thread background = new Thread(new Runnable() {
public void run() {
try {
 DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpPost post = new HttpPost(
 "http://uni111.ogame.fr/api/players.xml");
 try {
 HttpResponse res = httpClient.execute(post);
 HttpEntity entity = res.getEntity();
 long taille = entity.getContentLength();
 String xml = EntityUtils.toString(entity, "UTF-8");

while(CONDITION){

}

 Message msg = handler.obtainMessage();
 bu = new Bundle();
 bu.putString("xml", xml);
 msg.setData(bu);

 handler.sendMessage(msg);




 } catch (ClientProtocolException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (Exception e) {
 Log.e("Error", e.toString());
 }
} catch (Exception e) {
 Log.e("Error", e.toString());
}
}
});
background.start();
}
}

Share this post


Link to post
Share on other sites

J'ai pas testé je te dit ça un brin au feeling, mais au lieu de faire un EntityUtils.toString si tu partais plutôt sur un inputstream lu par un bufferedreader avec entity.getContent().

Après ton stream tu peux le lire ligne par ligne et gérer une progression je pense.

Share this post


Link to post
Share on other sites

J'avais fait ça avant d'adopter cette méthode, et effectivement j'arrivais a faire la mise a jour du progressBar.

Mais j'aimerai savoir si c'est la bonne méthode a utiliser?

Si non j'avais penser a boucler lors du download du flux xml lorsque je fait la requête http.

Merci

Share this post


Link to post
Share on other sites

Ben moi je pense que le stream c'est le mieux et tu gères ta progressbar dans la boucle de lecture.

Le principe du stream est justement de gérer le chargement du fichier, tu te connectes au flux et tu prends ce que tu veux à l'endroit que tu veux quand tu veux puis tu te déco du flux.

Comme un streaming vidéo, bon là tu souhaites seulement le charger dans une variable donc ben t'envoies une boucle qui s’arrêtera à la fin.

Aussi rapide que le télécharger d'un coup mais tu connais la taille et tu peux décider de la quantité de donnée qui sera lu à chaque tour de la boucle (ou si tu lis par ligne t’arrêter quand il n'y en a plus).

Mets le dans un stringbuilder si t'utilises la boucle, un string simple n'est pas fait pour subir des modifications et te fera consommer plus de mémoire.

Share this post


Link to post
Share on other sites

Salut,

Hey bien,ta réponse est très clair et tu m'a bien éclairé ma pauvre lanterne.

Je ne connaissais pas le stringbuilder, je vais voir la doc.

Je te tiens au courant, merci de ton aide.

PS: une question, faut t-il détruire mon thread lors du OnDestroy()?

Share this post


Link to post
Share on other sites

Euh non java va gérer ça tout seul, et vu que ton thread ne peut pas être bloquant (il se finira toujours) ben tu n'as pas besoin de protection.

Si tu ne l'utilises qu'à un endroit t'es même pas obligé de déclarer une variable, au lieu de faire ça :

Thread background = new Thread(new Runnable() {
...
});
background.start();

Tu peux abréger :

new Thread(new Runnable() {
...
}).start();

Edit: Tu peux quand même vérifier si il est fini à l'extinction du soft et si il ne l'ai pas l'arreter, faut voir par rapport à la taille de ton xml si c'est nécessaire.

Share this post


Link to post
Share on other sites

Salut,

Dois je comprend que à chaque ajout de texte dans un objet de type String, on recréer une nouvelle instance ?

par exemple:

String text = "du texte";
text += " et un peu plus";

donc si c'est le cas, dans une boucle avec plein d’itération je comprend l'importance d'utiliser StringBuilder

Share this post


Link to post
Share on other sites

Oui c'est exactement ça :)

Un string au fond n'est pas modifiable, à chaque fois que tu déclares un string il va directement s'allouer sa place en mémoire, à chaque fois que tu le modifies il en crée un autre.

Le stringbuilder permet de ne pas avoir ce soucis ce qui fait que dans une boucle un string avec += ça se fait pas du tout.

Une fois que tu l'as construis à coup d'append tu peux le récupérer facilement dans un string avec ".toString()".

Share this post


Link to post
Share on other sites

Je voudrais stocker temporairement le flux xml étant donné que ce dernier est mise à jour une fois par semaine, histoire de ne pas faire de requête pour rien.Je peux insérer les données dans la base de donné proposé par Android ou bien mettre en cache les données.

J'aimerai savoir quelle solution est la plus adapté.

Merci

Share this post


Link to post
Share on other sites

Le plus simple et le plus adapté à ton cas, je pense, serait de stocker en cache le flux XML, dans un fichier. Ton application sait traiter un flux XML, alors que celui-ci provienne du réseau ou d'un fichier, ça ne fera pas grande différence. Stocker tes données en base nécessiterait de transformer tes données pour les adapter à un format base de données (et vice-versa pour les relire...)

Share this post


Link to post
Share on other sites





×
×
  • Create New...