Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 (modifié) Salut, Je suis en train de m'arracher les cheveux sur un point qui ne me parait pourtant pas bien compliqué. Dans mon activité (Uploader) j'affiche tout d'abord un AlertDialog qui m'affiche plusieurs choix pour uploader un photo. En fonction de l'item sélectionné, j'effectue différentes opérations. Par exemple, dans le cas où "Email" est sélectionné,j'appelle ma fonction sendByEmail au sein d'un ProgressDialog. Ce que j'aimerais, c'est pouvoir afficher un Toast une fois mon ProgressDialog disparu. Et j'ai beau essayé de le déclarer un peu partout, je n'arrive pas à l'afficher... Des idées ??? Voici le code: (...) final CharSequence[] Uploads = { "Email", "HTTP Post", "GAME","Flickr"}; AlertDialog.Builder alt_bld = new AlertDialog.Builder(Uploader.this); alt_bld.setIcon(R.drawable.send); alt_bld.setTitle(R.string.send_by); alt_bld.setSingleChoiceItems(Uploads, 0, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { switch(item){ case 0: // Je vire mon AlertDialog pour pouvoir afficher mon Progress Dialog alert.cancel(); dialogUp = ProgressDialog.show(Uploader.this, "", getResources().getString(R.string.progress_dialog_http_send), true); new Thread() { public void run(){ try{ String to = mailSendTo; sendByMail(filename, to); Toast.makeText(Uploader.this, "Message envoyé !", Toast.LENGTH_SHORT); }catch(Exception e){} dialogUp.dismiss(); } }.start(); } break; case 1: ( ... ) } alert.cancel(); } }); alert = alt_bld.create(); alert.show(); Modifié 7 mai 2010 par Bertrand31 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
arthur Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 euh je suis pas sûr de moi mais il faut pas mettre un .show() après Toast.makeText(...) ? Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 euhhh je vais essayer, mais si c'est ça, je saute par la fenêtre :rolleyes: Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 En laissant le Toast au sein du thread, rien de s'affiche, par contre si je le place après le dialogUp.dismiss(), donc si j'ai bien compris, après que mon progressDialog disparaisse, j'ai au moins un plantage de l'application : Can't create handler inside thread that has not called Looper.prepare() E/AndroidRuntime( 6664): at android.os.Handler.(Handler.java:121) E/AndroidRuntime( 6664): at android.widget.Toast.(Toast.java:397) E/AndroidRuntime( 6664): at android.widget.Toast.makeText(Toast.java:230) E/AndroidRuntime( 6664): at com.spotimage.uploader.Uploader$2$2$3.run(Uploader.java:238) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
arthur Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 bon, honnêtement, j'y connais rien. mais voilà ce que je ferais: - déjà avant que tu déplaces le Toast.maketext(...) est-ce qu'il y avait une exception? Tu devrais mettre un log.e(....) dans le catch(exception) {}, t'apprendras ptetre quelque chose... - j'essaierais de changer le contexte du Toast.makeText(context,...) . Me demande pas pourquoi. - tu peux essayer d'ajouter Looper.prepare() juste au début du Runnable mais à mon avis c'est un gros outil pour juste un petit Toast - t'as mis le .show() finalement? ... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Bon j'ai remis le Toast après ma fonction sendByMail() (avec .show) J'ai mis un Log dans la balise exception qui me renvoie la même erreur : Can't create handler inside thread that has not called Looper.prepare() Au niveau du contexte j'ai modifié par "getApplicationContext()" , et j'ai la même erreur. Et puis l'histoire du Looper.prepare() je suis pas sûr d'avoir capté à quoi servait le machin ... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fluckysan Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 (modifié) C'est un peu mélangé en fait :o Dans un premier temps, refais l'enchaînement de tes actions : Utilise une Activity avec un thème Dialog que tu lanceras avec startActivityForResult Une fois le choix fait par l'utilisateur dans ta liste, tu retournes un résultats dans ton Activity (et les infos dont tu as besoin) Tu récupère ensuite ton résultat et tes infos via onActivityResult, tu y fais ton switch et ton Thread (il faut le déclarer / construire séparément puis le lancer ici) Dans ton Thread et une fois le traitement fini, tu notifies ton Activity que tout est fini (via un Handler) Dans ton Handler tu t'occupes d'arréter ta ProgressDialog et d'afficher ton Toast (il faut bien le .show() pour l'afficher C'est la façon de faire que j'utiliserais :) Modifié 6 mai 2010 par Fluckysan Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Ouais, ça veut dire que j'ai pas mal de code à revoir... C'est dommage parce que c'était juste pour afficher un petit Toast informant l'utilisateur que sa photo avait bien été uploadée ... Je vais quand même jeter un œil à ta solution s'il me reste un peu de motiv' Merci Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Profete162 Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 C'est un probleme que je rencontre beaucoup aussi et ton erreur m'est vraiment familière. J'ai aussi beaucoup de mal à comprendre ces threads avec des alertdialog et un toast qui ne sait pas s'afficher en meme temps! C'est assez casse-tête et pas vraiment intuitif Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Pro-fête , tu t'en sors comment de ce problème en général ? Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fluckysan Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Il ne faut pas que tu te démotives ! Si tu y va petit à petit ça va aller et tu vas voir que ça sera beaucoup plus clair après :) Je précise que la façon de faire que je t'ai indiqué, c'est une des façon possible et que toute ses modifications ne sont pas uniquement pour afficher le Toast mais pour apporter de la clarté à ton code et se faisant l'affichage du Toast est beaucoup plus simple ! Je te conseille de jeter un oeil à ce tuto : http://www.helloandroid.com/tutorials/using-threads-and-progressdialog Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Oui je comprends, c'est juste que c'est une application que je développe en stage, ça fait 1 mois que je suis dessus, et là je voulais juste finaliser esthétiquement. Ça m'embête un peu de revoir ce gros bout de code sachant que j'ai une démo Lundi :( Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fluckysan Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Hum je comprends :/ On ne peut pas afficher de Toast dans un Thread, d'où le message d'erreur Dans l'urgence tu peux prendre seulement la partie Handler du tuto : Créer un Handler avec ton Toast.show() dans son handleMessage Remplace ton Toast.show() de ton Thread par un tonHandler.sendEmptyMessage(0) Tu peux ensuite adapter ton Handler avec un switch suivant ce que tu lui envois pour afficher différent message Ca devrait faire l'affaire pour ta démo (bout de scotch lol) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Ouais je viens de survoler ton lien, ça peut faire l'affaire je pense. En plus, je veux juste afficher le même message pour mes différents case: Donc un seul handler suffira. :D En tous cas merci à tous ! Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Alocaly Posté(e) 6 mai 2010 Share Posté(e) 6 mai 2010 Hum... J'arrive apres la bataille, et comme j'ai juste survolé, je peux me planter, mais : Tout ce qui est UI doit se faire dans le thread principal. Donc est-ce que ton probleme n'est pas juste que tu essaye de lancer un toast dans un thread non principal ( et que cette limitation s'applique aux toasts, ce dont je ne suis pas entierement persuadé ). La bonne nouvelle, c'est que si c'est ca, c'est pas mal prévu par Android : ils ont fait une fonction spéciale 'runOnUiThread' pour lancer une commande dans le bon thread. donc peut etre que qq chose de ce gout la marcherait : runOnUiThread(new Runnable() { public void run() { Toast.makeText(this, "pouetpouet", Toast.LENGTH_SHORT).show(); } }); Emmanuel / Alocaly Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Invité Posté(e) 7 mai 2010 Share Posté(e) 7 mai 2010 Hallelujah mes frères !! :D Effectivement Alocaly, tu as trouvé la solution à mon problème !!! Je ne connaissais pas l'existence de runOnUiThread . Ça m'ouvre pas mal d'horizon sur des améliorations d'ergonomie . J'édite le sujet de ce pas. Merci bien. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Alocaly Posté(e) 7 mai 2010 Share Posté(e) 7 mai 2010 Ah ??? :) Bon, ben c'est super !! En meme temps, je ne comprends pas tout moi : hier, juste apres avoir écrit ce message, j'ai modifié une appli à moi en remplacant un toast par la mise à jour d'une textView : alors que le toast marchait sans soucis, la mise à jour du textview ne marchait pas, et j'ai du mettre un runOnUiThread pour le faire marcher. Alors qu'avec mon toast, je n'en avais pas besoin... ( et du coup, je m'etais dit que je m'etais planté avec mon post :) ) Bon, ben le principal c'est que ca marche chez tout le monde, non :) ?? Emmanuel / Alocaly Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
naholyr Posté(e) 7 mai 2010 Share Posté(e) 7 mai 2010 Cool ce runOnUiThread ! je ne connaissais pas non plus, ça peut grandement simplifier des situations où on est obligés de passer par un Handler et des sendMessage... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
dawadam Posté(e) 24 novembre 2011 Share Posté(e) 24 novembre 2011 (modifié) Salut Merci pour le "runOnUiThread" que je ne connaissais pas non-plus. Jusqu’à maintenant j'utilisais uniquement le Handler.Callback qui fonctionne bien d’ailleurs. Il faut bien ce faire au fonctionnement Android :) Mais, même avec Handler, on peut tomber sur ce message d'erreur : // Can't create handler inside thread that has not called Looper.prepare() En fait, on cré le handler comme ça : Handler handler = new Handler(callback); // callback est un Handler.Callback On fait sa dans le UI et on peut ensuite transmettre le Handler dans n'importe quel Thread. En retour il suffit d'utiliser : handler.sendMessage(message); // message est un android.os.Message Et donc la méthode du Callback sera appelée (qui est l'interface à implémenter dans notre activité) C'est pas simple, mais c'est comme ça... Sinon il y a cette fameuse méthode runOnUiThread pour ceux qui ne veulent pas y penser -_- Au cas où un exemple d'une méthode static pour faire un traitement dans un autre Thread et renvoyer la réponse à un callback : public static void getInternetPage(Handler.Callback callback, final int code) { // handler (ne surtout pas créer dans l'autre Thread, il faut que ce soit commandé par l'UI) final android.os.Handler handler = new Handler(callback); // thread new Thread(new Runnable() { @Override public void run() { // l'action qui prend du temps et donc requière le Thread Page page = connectionPourTelechargerUnePage(); // envoi le retour (code retour pratique si plusieurs callback) android.os.Message msg = new android.os.Message(); msg.what = code; msg.obj = page; handler.sendMessage(msg); } }).start(); } Modifié 25 novembre 2011 par dawadam Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Rejoignez la conversation
Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.