IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

ProgressBar mise à jour depuis une autre classe


Sujet :

Android

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut ProgressBar mise à jour depuis une autre classe
    Bonjour,
    Il existe pas mal de tutos sur les progressbar sur le web, mais j'ai remarqué que c'est à peu près tous les mêmes, et ils ne correspondent pas tout à fait à ce que je recherche.

    Je suis en train de développer une appli avec un splashscreen au démarrage, parce qu'au lancement de l'application je vais chercher des infos sur un serveur distant, des infos que je reçois en JSON, etc...

    Bref, pendant tout ce temps il me faut une progressbar qui avance sur mon splashscreen. Je souhaite que cette progressbar avance en fonction de ce qui à été traité dans ma classe qui s'occupe d'exploiter les données JSON. Donc je voudrais que cette classe, qui est executée en arrière plan, donne régulièrement un signal à l'activity en cours (le splashscreen) afin de faire avancer la progressbar.

    Je ne sais pas si j'ai été assez clair, je ne sais pas trop comment expliquer plus clairement...

    En tout cas si vous saisissez a peu près ce que je recherche, pouvez-vous me donner quelques pistes ?

    Merci

  2. #2
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Cette tâche étant forcément en arrière plan (pour éviter les ANR), elle utilise un thread ou un AsyncTask.

    La deuxième solution est la plus simple puisque AsyncTask propose de base la gestion de la "progression" (il y a juste à appeler régulièrement une fonction, et surcharger le onProgressUpdate [ou du genre] pour aller modifier la progress bar).

    La première solution passe par l'utilisation de Handler (forcément utilisés pour notifier le thread UI de la fin du loading)... Et la, régulièrement, il faut 'poster' un runnable qui va mettre à jour la barre de progression.

  3. #3
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Si la progression est inquantifiable (ou très difficile à quantifier ... telle action représente combien ? et si j'en ai X ? mais si 2 actions identiques représentes X mais s'exécutent en des temps très différents ? ...), plutôt utiliser un style de spinner, avec les informations de ce qui est en train de se passer au besoin.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Tiens, je ne connaissais pas AsyncTask...
    Il y a peut-être moyen de creuser la dessus en effet...
    Je vais y aregarder de plus près.

    Je comprends bien que ce genre de tâches sont en arrière plan, mais les tutos que j'ai vu sur le threads et progressbar utilisent qu'une seule "activity" a chaque fois... or moi, je souhaite utiliser mon activity (splashscreen) pour la progressbar, sachant que l'importation des données est réalisée dans un autre fichier "class", et ce que je n'arrive toujours pas, c'est de transmettre l'état de la progressbar d'un fichier à l'autre.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Je viens de voir AsyncTask, ça correspondrait a ce que je recherche,
    mais ma classe qui execute la tache de fond contient plusieurs threads (je peux exécuter plusieurs taches de fond différentes), donc je ne peux pas tout mettre dans "doInBackground"...

    Donc la seule solution pour moi est la solution du Handler ?

    Dans ce cas, comment passer un runnable régulièrement pour actualiser la progressbar ? J'ai beau chercher, je ne comprends pas comment ça marche...

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2011
    Messages : 144
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par poussinvert Voir le message
    Je viens de voir AsyncTask, ça correspondrait a ce que je recherche,
    mais ma classe qui execute la tache de fond contient plusieurs threads (je peux exécuter plusieurs taches de fond différentes), donc je ne peux pas tout mettre dans "doInBackground"...
    Rien ne t'empêche d'utiliser plusieurs AsyncTask.
    Ton activité (ou même une AsyncTask) peut très bien lancer d'autres AsynTask pour faire plusieurs traitement. Ne soit pas non plus trop gourmand car il y a une limite (5 en même temps).

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juin 2010
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Je ne sais pas du tout si cela peux t'aider
    mais j'avais codé ça en m'inspirant de plusieurs exemples et thread sur le forum.
    La classe mets à jour une progressBar dans une nouvelle fenêtre modale.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
     
    public class SqlToCsv_SwingWorker 
    {
    	private static Logger _logError = Logger.getLogger( SqlToCsv_SwingWorker.class );
    	private final Launcher _launcher;
    	private final JLabel _info = new JLabel( "Progression .... " );
    	private JProgressBar _progressbar;
    	private int nbProd;
     
    	public SqlToCsv_SwingWorker( final Launcher launcher ) 
    	{
    		_logError.info( "Lancement export BDD to CSV" );
    		_launcher = launcher;
    		nbProd = getNbProduct();
    		_progressbar = new JProgressBar( 0, nbProd );
     
    		EventQueue.invokeLater(new Runnable() {
    			@Override public void run() {				
                    runCalc();
                }
            });
    	}
     
    	public void runCalc() 
    	{
    		final JDialog dlg = new JDialog( _launcher, "Progress Dialog", true );
    //	    JLabel dpb = new JLabel( "toto" );
    		dlg.add(BorderLayout.CENTER, _progressbar);
    	    dlg.add(BorderLayout.NORTH, _info);
    	    dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
    	    dlg.setSize(300, 75);
    	    dlg.setLocationRelativeTo(_launcher);
     
    		_progressbar.setIndeterminate( true );
            TwoWorker task = new TwoWorker( dlg );
            task.addPropertyChangeListener( new PropertyChangeListener() {
                @Override public void propertyChange(PropertyChangeEvent e) {
                    if( "progress".equals(e.getPropertyName()) ) {
                    	_progressbar.setIndeterminate( false );
                    	_progressbar.setValue( (Integer)e.getNewValue() );
                    }
                }
            });
     
            task.execute();
            dlg.setVisible( true );
        }
     
    	private class TwoWorker extends SwingWorker<Void, Integer>
    	{
    		private final JDialog _dial;
    		public TwoWorker( final JDialog dial ) {
    			super();
    			_dial = dial;
    		}
            @Override protected Void doInBackground() throws Exception {
            	InputSql inputSql = new InputSql( "" );
        		Product prod;    		
        		final SqlQuery sql = new SqlQuery();
        		try 
        		{
        			sql.connect();
        			ResultSet rs = sql.requete( "SELECT id FROM produit" );
        			try { 
    	    		    int currentRow=0;
    	    			while( rs.next() )
    	    			{
    	    				setProgress( (currentRow*100)/nbProd );
    	    				publish( currentRow );
    	    				String id_prod = rs.getString( 1 );				
    	    				inputSql.setIdProduit( id_prod );
    	    				prod = new Product();
    	    				prod = inputSql.getProductInformation();
    	    				String product_sirom = format( prod );
    	//    				save( product_sirom );
    	    		        currentRow++;
    	    			}	
        			}
        			finally {
        				rs.close();
        			}
        			sql.close();
        		} 
        		catch( SQLException e ) {
        			_logError.error( "Erreur sql lors de la récupération des informations" +
        					"necessaires pour l'export csv" + e );
        			JOptionPane.showConfirmDialog( null,
        					"ERREUR sql pendant l'export de la base de données\n" +
        					"Le fichier csv de sortie est incomplet.", "Confirm",
        			        JOptionPane.YES_OPTION, JOptionPane.ERROR_MESSAGE );
        			e.printStackTrace();
        		}	
        		finally {
        			_dial.setVisible( false );
        		}
        		return null; 
            }
            @Override protected void process(List<Integer> chunks) {
            	_info.setText( "Sauvegarde du produit " + chunks.get(chunks.size()-1) 
            			+ " sur " + nbProd );
            	_progressbar.setValue( chunks.get(chunks.size()-1) );
            }
    	}
    }

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    gilloddon, mes différentes tâches de fond ne sont pas à exécuter en même temps, et puisqu'elles réalisent des actions différentes, je ne peux pas toutes les mettre dans "doInBackground". Et je peux avoir qu'un seul "doInBackground" dans ma class...
    En fait, j'ai plusieurs Threads dans ma class, mais je ne les appelle pas forcément en même temps.
    Je pense qu'il faut que je continue avec la première solution de nicroman : Plusieurs threads, avec remontée de "où on en est" à l'utilisateur. Mon problème, c'est comment remonter un état sur l'activity avec les Objets Runnable, Handler, etc...
    Comment remonter un truc qui fasse avancer ma progressbar ?

    teroux, Je ne comprends pas trop ton code, on dirait qu'il est appliqué a une appli JAVA, mais pas pour un context Android... Je peux manipuler ma progressbar uniquement dans mon activity, mais pas dans ma class qui execute l'import en tâche de fond.

  9. #9
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2011
    Messages : 144
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par poussinvert Voir le message
    gilloddon, mes différentes tâches de fond ne sont pas à exécuter en même temps, et puisqu'elles réalisent des actions différentes, je ne peux pas toutes les mettre dans "doInBackground". Et je peux avoir qu'un seul "doInBackground" dans ma class...
    Pourquoi tu ne pourrais pas faire toutes tes actions dans une seule AsyncTask alors ?
    Créé un constructeur pour ton AsyncTask, avec tout les paramètres et données nécessaires, puis fais le traitement dans le doInBackground. A la limite, pour y voir plus clair, tu peux aussi créer quelques méthodes dans ta classe héritant de l'AsyncTask pour faire différents traitements à la suite.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par gilloddon Voir le message
    Pourquoi tu ne pourrais pas faire toutes tes actions dans une seule AsyncTask alors ?
    Créé un constructeur pour ton AsyncTask, avec tout les paramètres et données nécessaires, puis fais le traitement dans le doInBackground. A la limite, pour y voir plus clair, tu peux aussi créer quelques méthodes dans ta classe héritant de l'AsyncTask pour faire différents traitements à la suite.
    Mes différentes taches de fond sont en fait différentes requêtes a executer sur le serveur. Je récupère ensuite un JSONArray composé de JSONObject.
    Donc si je comprends bien, j'aurais au moins la requête* a passer comme paramètre à doInBackground.
    Dans ce cas là, j'ai encore plusieurs petites questions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected void onProgressUpdate(Integer... values)
    Pourquoi les 3 petits points après le type de donnée ?
    Si on les enlève, ça ne fonctionne plus...
    Pour appeler onProgressUpdate, je fais :
    Mais quel est le type de values ? Ce n'est pas un simple Integer, ni un tableau d'Integer, si ?

    je nage, je nage...

    *en fait, la requête c'est une URL qui appelle un fichier PHP qui renvient les données en JSON...

  11. #11
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juin 2010
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Tiens tu peux regarder le tutoriel ici sur les SwingWorker : http://rom.developpez.com/java-swingworker/
    Qui te permette de gérer une progressbar dans un thread.

    Sinon non cette classe construit une fenêtre avec une progressbar a l'intérieur
    et la méthode : @Override protected Void doInBackground() qui correspond au traitement que tu veux effectuer. Dedans tu mets à jour l'avancement avec setProgress( (currentRow*100)/nbProd ); et tu peux enfin mettre a jour ta progressbar avec : @Override protected void process().

    Voilà comme je l'ai dis je suis pas expert, je sais pas si cela peux t'aider.
    Bon courage.

  12. #12
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    @Teroux : Android utilise un sous-ensemble de Java, et n'utilise absolument pas Swing, donc tout ceci est inadapté ici (bien que la logique sous-jacente soit exactement la même).

    @poussinvert : Les "..." sont des paramètres ellipsés (ellipsize en anglais), c'est équivalent à un tableau d'objet.
    Donc Integer... values correspond à Integer values[].
    Pour la remarque "si je les enlève, ça ne fonctionne plus", c'est simplement parce que le prototype de la méthode que tu surcharges est ainsi. En changeant son prototype, sa signature, tu ne la surcharges plus, et donc => problème.

  13. #13
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2011
    Messages : 144
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par poussinvert Voir le message
    Donc si je comprends bien, j'aurais au moins la requête* a passer comme paramètre à doInBackground.
    Dans ce cas là, j'ai encore plusieurs petites questions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected void onProgressUpdate(Integer... values)
    Pourquoi les 3 petits points après le type de donnée ?
    ...
    *en fait, la requête c'est une URL qui appelle un fichier PHP qui renvient les données en JSON...

    Personnellement, je ne m'embête pas avec les paramètres de ces méthodes, je fais un constructeur (plus simple pour passer plein de paramètres, surtout quand ils sont de type différents).

    Petit exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class DownloadTask extends AsyncTask<Void, Void, Void>
    {
    	private int unEntier;
    	private String[] tabUrl;
    	private boolean uneCondition;	
     
            // Le constructeur pour passer les paramètres
    	public DownloadTask(int nb, String[] tabUrl, boolean truc)
    	{
    		this.unEntier = nb;
    		this.tabId = tabUrl;
    		this.uneCondition = truc;
    	}
     
     
    	@Override
    	protected Void doInBackground(Void... params)
    	{		
    		...
                    // fais ta requête http avec les adresses contenu dans le tableau
                    // ex: HttpGet httpget = new HttpGet(this.tabUrl[2]);
                    ...
            }
    Et pour appeler l'asynctask, tout simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DownloadTask dlTask = new DownloadTask(monEntier, monTabUrl, monBooleen);
    dlTask.execute();
    D'ailleurs, si tes urls sont fixes, autant faire des attributs statiques.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private static final String URL_PAGE1 = "http://monsupersite.com";
    Et du coup, pas besoin de passer des adresses en paramètres.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HttpGet httpget = new HttpGet(URL_PAGE1);

  14. #14
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Et en utilisant les paramètres de l'AsyncTask (sont là pour ça), la classe de Gillodon deviendrait (avec le passage du ProgressDialog, c'est le seul ajout) :

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class DownloadTask extends AsyncTask<String, Integer, Void>
    {
    	private int unEntier;
    	private String[] tabUrl;
    	private boolean uneCondition;
     
    	private ProgressDialog progressDialog;
     
            // Le constructeur pour passer les paramètres
    	public DownloadTask(int nb, boolean truc, ProgressDialog dialog)
    	{
    		this.unEntier = nb;
    		this.uneCondition = truc;
     
    		progressDialog = dialog;
    	}
     
    @Override
    protected void onProgressUpdate(Integer... values)
    	{
    		super.onProgressUpdate(values);
     
    		// mettre à jour la progress bar ici, méthode exécutée dans le thread graphique. 
     
    		progressDialog.setProgress(values[0]);
     
    	}
     
    @Override
    	protected Void doInBackground(String... params)
    	{
    		tabUrl = params;
                    // fais ta requête http avec les adresses contenu dans le tableau
                    // ex: HttpGet httpget = new HttpGet(this.tabUrl[2]);
     
    		// exemple de publication, ici onProgressUpdate() est invoquée avec la valeur de 15
    		publishProgress(15);
     
    		return null;
            }
    }

    Et s'utilise :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DownloadTask task = new DownloadTask(nbDL, condArret, progressDialog);
    task.execute(tabDURL);

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Ok,
    Après une petite pause je m'y remets...
    Merci pour l'exemple, j'essaie de voir ce que je peux faire avec ça.
    Je ne savais pas que l'on pouvais surcharger onProgressUpdate.

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Ah non ok, j'ai mal lu, tu n'as pas surchargé onProgressUpdate

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Bon, y'a un début. Et même un très bon début...
    Ca marche bien, mais en fait ma progressbar est censée avancer en fonction du téléchargement des données. Pour vous expliquer, voici mon doInBackground :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    @Override
    protected JSONArray doInBackground(String... params)
    	{	
    		final HttpClient httpClient = new DefaultHttpClient();				
    		try {
    			HttpGet httpGet = new HttpGet(params[0]);
    			HttpResponse httpResponse = httpClient.execute(httpGet);
    			HttpEntity entity = httpResponse.getEntity();
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
     
    			if (entity != null) {
     
    				/********    Petite moulinette qui va chercher les données  *****/
    				InputStream inputStream = entity.getContent();
    				BufferedReader bufferedReader = new BufferedReader(
    						new InputStreamReader(inputStream));
    				StringBuilder stringBuilder = new StringBuilder();
    				String ligneLue = bufferedReader.readLine();
    				int i = 0;
    				while (ligneLue != null) {
    					i++;
    					publishProgress(i);
    					try {
    						Thread.sleep(1500);
     
    					} catch (InterruptedException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					stringBuilder.append(ligneLue + "\n");
    					ligneLue = bufferedReader.readLine();
    				}
    				inputStream.close();
    				/**************************************************************/
     
    				jsonResultSet = new JSONArray(stringBuilder.toString());
    			}
    		} catch (IOException e) {
    			Log.e("ClientJSON", e.getMessage());
    		} catch (JSONException e) {
    			Log.e("ClientJSON", e.getMessage());
    		}
     
    		return jsonResultSet;
     
            }
    Pour résumer je télécharge les données, et j'ai rajouté des "sleep" parce qu'en wifi ça va trop vite.
    Et mon problème, c'est juste que la barre a avancé de 1px seulement. En même temps, je n'ai pas précisé le max de la progressbar... ça risque pas d'avancer...

    Bon et puis l'autre problème, plus embêtant, c'est que mon Spashscreen ne s'affiche que lorsque les données sont téléchargées, donc aucun intéret...

    Donc j'ai placé l'appel de la fonction dans un thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    new Thread(new Runnable() {
     
    		public void run() {
     
    		       // appel de la fonction qui elle-même fait appel a ma classe AsyncTask
     
                           //Quand c'est téléchargé, le Handler ferme le splashscreen et ouvre l'activité principale.
    		       splashHandler.sendEmptyMessage(0);
     
    		}
     
           }).start();
    ... mais l'application ferme au démarrage

    Comment faire ?

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Après diverses recherches...

    Bon visiblement il ne faut surtout pas mettre de thread autour de l'appel de l'AsyncTask (pas de thread dans un thread).
    Pour l'histoire de l'affichage retardé du splash screen, j'ai trouvé une piste :
    Voici mon code qui pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DownloadData download = new DownloadData(mProgressBar, this); 
    		AsyncTask<String, Integer, JSONArray> async = download.execute(params);
    		try {
    			JSONArray datas = async.get();
    			System.out.println(datas.toString());
    		} catch (InterruptedException e1) {
    			// TODO Auto-generated catch block
    			e1.printStackTrace();
    		} catch (ExecutionException e1) {
    			// TODO Auto-generated catch block
    			e1.printStackTrace();
    		}
    C'est le try qui pose problème : En effet, lorsque tout est téléchargé, je souhaite récupérer mon JSONArray... mais visiblement ça ne lui plait pas...

    Du coup, je suppose qu'il faut faut renvoyer les données dans l'activity principale (càd dans le splashscreen) à partir de onPostExecute().

    Mais que mettre dans onPostExecute() ? Comment détecter la fin du téléchargement dans l'activity ? ...

    Je cherche, je cherche... sur le web, etc.. mais si quelqu'un peut me répondre ça serait nickel =)

  19. #19
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Les AsyncTask sont assez simple:

    Il y a deux threads: l'UI et le Worker de l'AsyncTask:

    [UI] Création de l'AsyncTask<PARAM,PROGRESS,RESULT> avec un tableau de PARAM en paramètres
    [UI] Appel de "execute"
    [Worker] Appel de RESULT doInBackground(PARAM ... )
    [Worker] Appel régulier de setProgress(PROGRESS...)
    [UI] Appel régulier de onProgressUpdate(PROGRESS...)
    [Worker] Fin du traitement avec retour de "RESULT"
    [UI] Appel de onPostExecute(RESULT)

    Donc l'idéal, c'est que l'activity crée le AsyncTask dans son onCreate()... et le démarre.
    L'AsyncTask est sensé retourner un JSONArray (Async<?,?,JSONArray>)

    Le "doInBackground" s'écrit alors comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    JSONArray doInBackground(? .)
    {
         JSONArray ret = null;
         try {
           ret =  ...
         } catch (..) { ... }
         return ret;
    }
    Et le onPostExecute:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void onPostExecute(JSONArray ret) {
       MyActivity.this.onTaskEnded(ret);  // <= si l'AsyncTask est une classe fille de l'activité, sinon, on peut passer un paramètre pour le callback
    }
    Et voila, à la fin de l'async task, l'activité recevra un appel avec onTaskEnded et le JSONArray associé ... libre à l'activité de faire autre chose (comme lancer une autre activité puis se fermer).

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 256
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par nicroman Voir le message
    Les AsyncTask sont assez simple:

    Il y a deux threads: l'UI et le Worker de l'AsyncTask:

    [UI] Création de l'AsyncTask<PARAM,PROGRESS,RESULT> avec un tableau de PARAM en paramètres
    [UI] Appel de "execute"
    [Worker] Appel de RESULT doInBackground(PARAM ... )
    [Worker] Appel régulier de setProgress(PROGRESS...)
    [UI] Appel régulier de onProgressUpdate(PROGRESS...)
    [Worker] Fin du traitement avec retour de "RESULT"
    [UI] Appel de onPostExecute(RESULT)

    Donc l'idéal, c'est que l'activity crée le AsyncTask dans son onCreate()... et le démarre.
    L'AsyncTask est sensé retourner un JSONArray (Async<?,?,JSONArray>)
    Oui oui, tu me confirmes ce que j'avais bien compris. J'ai réalisé exactement ça dans mon code, c'est à dire que je renvoie bien mon JSONArray. Ça c'est fais.

    Citation Envoyé par nicroman Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       MyActivity.this.onTaskEnded(ret);  // <= si l'AsyncTask est une classe fille de l'activité, sinon, on peut passer un paramètre pour le callback
    Eh bien justement, c'est ça ma question. Pour le doInBackground, c'est nikel, ça marche.
    En fait, AsyncTask n'est justement pas une classe fille, parce qu'elle pourra être appelé à partir de n'importe quelle classe, ou n'importe quelle activity (parce que justement, l'accès à la base ne se fait pas forcément uniquement depuis le splashscreen, on pourra par exemple "checker" la version ou les màj depuis d'autres activity, ou depuis un menu...)

    Et dans le onPostExecute, il faudrait qu'on rappelle la classe qui a appelé l'AsyncTask pour lui dire que le téléchargement est terminé et qu'elle puisse faire un pour récupérer le JSONArray et continuer la moulinette...

    Si tout cela n'est pas réalisable, voyons plus simple : disons qu'une seule classe pourra appeler l'AsyncTask (le splashscreen). Tu as écris "si l'AsyncTask est une classe fille de l'activité, sinon, on peut passer un paramètre pour le callback". Je suis dans le cas que ce n'est pas une classe fille. Du coup, c'est donc l'histoire du callback qui m’intéresse : Comment ça marche, le callback dans le splashscreen ? Comment le splashscreen saura que le téléchargement est terminé ? Je sais qu'il faut faire un truc dans le onPostExecute, mais quoi ?

Discussions similaires

  1. Mettre à jour un TextView depuis une autre classe
    Par thesmogs dans le forum Composants graphiques
    Réponses: 0
    Dernier message: 21/07/2013, 22h33
  2. Mise a jour d'une Form depuis une autre class
    Par raphi056 dans le forum C#
    Réponses: 1
    Dernier message: 19/12/2009, 13h44
  3. Réponses: 2
    Dernier message: 24/03/2009, 14h14
  4. [Débutant] Lancer procédure depuis une autre classe
    Par pugnator dans le forum Langage
    Réponses: 5
    Dernier message: 31/10/2005, 14h50
  5. Acces a un control depuis une autre classe
    Par schnito dans le forum MFC
    Réponses: 5
    Dernier message: 25/01/2004, 22h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo