Jump to content
bylkus59

Timer sous Android

Recommended Posts

Bonjour,

Je développe depuis peu sous android et la j'ai essayé d'utiliser un Timer mais impossible que cela fonctionne.

Voici mon code :

public class TestTimer extends Activity {

/** Called when the activity is first created. */

Timer t;

//@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

t = new Timer();

t.scheduleAtFixedRate(new Action(),6000,6000);

}

class Action extends TimerTask{

public void run(){

Toast my_message = Toast.makeText(TestTimer.this,"Cool", Toast.LENGTH_SHORT );

my_message.show();

}

}

}

Ce code est-il bon ? Car à chaque fois que je veux l'exécuter dans l'emulator Android il me lance une erreur dès le début.

Pourriez-vous m'aider please.

Share this post


Link to post
Share on other sites

Je n'ai jamais utilisé de timer mais je remarque que ta méthode "run" de ta classe timertask n'est jamais appelée

Edited by Femto

Share this post


Link to post
Share on other sites
The application TestTimer (process test.timer) has stopped unexpectedly. Please Try Again

Va falloir apprendre à utiliser le logcat ( disponible dans eclipse ou ddms) si tu veux de l'aide!

Share this post


Link to post
Share on other sites

Merci pour ta recherche.

Windows -> show view -> logcat ( ou autre si il n'est pas par défaut)

Share this post


Link to post
Share on other sites

voici ce qu eme donnes logcat :

09-22 11:59:30.366: ERROR/AndroidRuntime(932): FATAL EXCEPTION: Timer-0

09-22 11:59:30.366: ERROR/AndroidRuntime(932): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

09-22 11:59:30.366: ERROR/AndroidRuntime(932): at android.os.Handler.(Handler.java:121)

09-22 11:59:30.366: ERROR/AndroidRuntime(932): at android.widget.Toast.(Toast.java:68)

09-22 11:59:30.366: ERROR/AndroidRuntime(932): at android.widget.Toast.makeText(Toast.java:231)

09-22 11:59:30.366: ERROR/AndroidRuntime(932): at test.time.TestTime$Action.run(TestTime.java:36)

09-22 11:59:30.366: ERROR/AndroidRuntime(932): at java.util.Timer$TimerImpl.run(Timer.java:289)

Share this post


Link to post
Share on other sites

la réponse est dans le message d'erreur :)

Il faut faire Looper.prepare() avant d'utiliser Timer

n'oublie pas d'appeller Looper.myLooper().quit() à la fin (je suppose que c'est utile)

Share this post


Link to post
Share on other sites

Merci maintenant le programme se lance bien mais ne fonctionne pas car il ne m'affiche pas mes toast je ne comprends rien car si j'utilise ça dan sun projet java et remplace le toast par SyStem.out.println cela marche nickel mais dès que je passe sous Android rien ne fonctionne.

Voici mon code :

package test.time;

import java.util.Timer;

import java.util.TimerTask;

import android.app.Activity;

import android.os.Bundle;

import android.os.Looper;

import android.widget.Toast;

public class TestTime extends Activity {

/** Called when the activity is first created. */

Timer t;

int i = 0;

//@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

t = new Timer();

t.schedule(new Action(),0,1000);

}

class Action extends TimerTask{

public void run(){

Looper.prepare();

if(i==0){

Toast my_message;

my_message = Toast.makeText(TestTime.this,"Cool", Toast.LENGTH_SHORT );

my_message.show();

}

//Looper.myLooper().quit();

Looper.loop();

}

}

}

Edited by bylkus59

Share this post


Link to post
Share on other sites

C'est lié au Thread qui exécute ton code.

Ca veut dire qu'il faut que ce soit le MEME thread qui exécute :

Looper.prepare()

t = new Timer();

t.scheduleAtFixedRate(new Action(),6000,6000);

Looper.myLooper().quit()

Ce que je te conseille de faire en pratique :

dans ton onCreate :

Looper.prepare()

t = new Timer();

t.scheduleAtFixedRate(new Action(),6000,6000);

dans ton onDestroy :

t.cancel()

Looper.myLooper().quit()

Il faut donc que tu gardes ton Timer en variable d'instance

Tu peux aussi placer ton code dans onStart/onStop ou onResume/onPause (tout dépend de ce que tu veux faire)

Je pense que ça devrait marcher (n'étant pas un spécialiste sur ce point... ), mais c'est ce que je ferai :)

Share this post


Link to post
Share on other sites

oups désolé, je viens de m'apercevoir que mon raisonnement est erroné :s

ce n'est pas Timer qui nécessite un Looper, mais le Toast :s

tout ce que je t'ai dit n'est donc pas valide

(j'avais mal lu le message d'erreur)

Share this post


Link to post
Share on other sites

si j'étais toi, j'essayerai plutôt d'exécuter le code de ton Toast dans le thread graphique... (via Activity.runOnUiThread(Runnable action))

Share this post


Link to post
Share on other sites

Ce n'est pas grave Pierre87 cela arrive à tout le monde et je vais pas me plaindre car tu es l'un des rares à me donner un coup de main.

J'ai mis précédemment cette fois-ci l'application se lance sans erreur mais elle n'effectue rien!

Share this post


Link to post
Share on other sites

Oula là je n'ai rien compris je ne vois même pas de quoi tu parle donc pourrais-tu m'expliquer où me donner un morceau de code m'illustrant ton propos stp

Share this post


Link to post
Share on other sites

je vais essayer de voir ce que je peux faire avec ton code...

(moi aussi ça m'intéresse)

je poste un message si j'ai une solution

Share this post


Link to post
Share on other sites

Une solution pas très élégante, mais qui marche :

public class TestTimer extends Activity
{
   Timer t;

   public void onCreate(Bundle savedInstanceState)
   {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       t = new Timer();
       t.scheduleAtFixedRate(new Action(), 6000, 6000);
   }

   protected void onDestroy()
   {
       super.onDestroy();

       t.cancel();
   }

   class Action extends TimerTask
   {
       public void run()
       {
           TestTimer.this.runOnUiThread(new Runnable()
           {
               public void run()
               {
                   Toast my_message = Toast.makeText(TestTimer.this, "Cool", Toast.LENGTH_SHORT);
                   my_message.show();
               }
           });
       }
   }
}

Utiliser Toast nécessite de se trouver dans le UI Thread

Share this post


Link to post
Share on other sites

c'est la seule solution que j'ai trouvé :/

Afficher un Toast nécessite d'être dans le main/UI thread

Or, l'exécution d'une TimerTask se fait dans un AUTRE thread

Il faut donc demander explicitement à ce que l'action soit faite dans le UI thread

Il y a peut être un moyen plus simple de le faire, mais je ne le connais pas...

Un code qui explique un peu mieux :

public class TestTimer extends Activity
{
   Timer t;

   public void onCreate(Bundle savedInstanceState)
   {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       t = new Timer(true);
       t.scheduleAtFixedRate(new Action(), 6000, 6000);

       System.out.println("UI thread : " + Thread.currentThread().getName());
   }

   protected void onDestroy()
   {
       super.onDestroy();

       t.cancel();
   }

   class Action extends TimerTask
   {
       public void run()
       {
           System.out.println("action thread : " + Thread.currentThread().getName());

           TestTimer.this.runOnUiThread(new Runnable()
           {
               public void run()
               {
                   System.out.println("toast thread : " + Thread.currentThread().getName());

                   Toast my_message = Toast.makeText(TestTimer.this, "Cool", Toast.LENGTH_SHORT);
                   my_message.show();
               }
           });
       }
   }
}

Share this post


Link to post
Share on other sites

Merci grâce à ton code et tes explications j'ai compris mon erreur et le fonctionnement du timer.

Moi je pensais que par defaut le toast savait qu'il devait s'afficher dans le main/Ui threads et non que je devais explicitement lui indiquer.

En tout cas encore merci car je ne pensais jamais en voir le bout de ce problème.

Et Pierre87 j'ai une petite information à te demander!

As-tu déjà programmer une application android utilisant l'API android.bluetooth?

Share this post


Link to post
Share on other sites

Oui, généralement, toute action qui a un impact sur l'affichage nécessite d'être exécutée par le thread main/UI/graphique.

Oui, j'ai déjà utilisé le bluetooth (c'est à la fois simple et compliqué)

Share this post


Link to post
Share on other sites

a beh génial car impossible de trouver un tuoriel clair expliquant toutes les étapes nécessaires!

Pourrais-tu si cela ne te derange pas m'envoyer ton code source de cette application afin de voir comment se déroule les différentes étapes comme :

Allumage bluetooth

Detection autre périphérique

Connexion au périphérique

Et Envoi et Reception de données

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.






×
×
  • Create New...