2011-02-01 2 views
0

J'ai eu quelques réponses, et nous sommes allés de l'avant et essayé ce qui suit:encore des difficultés à mettre fin à un fil

01 import android.app.Activity; 
02 import android.media.MediaPlayer; 
03 import android.os.Bundle; 
04 import android.os.Handler; 
05 import android.os.Message; 
06 import android.media.MediaPlayer; 
07 import android.media.AudioManager; 
08 import android.content.Context; 
09 import java.lang.Runnable; 
10 
11 public class CanvasDrawingActivity extends Activity { 
12  
13  private static final int FIRE = 0; 
14  private int initVolume = 0; 
15  private Handler handler; 
16  private MyCanvas v; 
17  private MediaPlayer mp; 
18  private AudioManager am; 
19  private MyRunnable r;// this is our custom runnable! 
20 
21  @Override 
22  public void onCreate(Bundle savedInstanceState) { 
23   super.onCreate(savedInstanceState); 
24   
25   am = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE); 
26    
27    // this method gets the current volume setting for music 
28    initVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC); 
29    
30    // this method sets the volume for music | the 100 is the volume. you can put there either initVolume or whatever value you want 
31    am.setStreamVolume(AudioManager.STREAM_MUSIC,100,AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 
32   
33   mp = MediaPlayer.create(this, R.raw.siren_1); 
34   
35   makeHandler(); 
36   v =new MyCanvas(this); 
37   setContentView(v); 
38   r = new MyRunnable();// this needs to create a new MyRunnable 
39   new Thread(r).start(); 
40   mp.setLooping(true); 
41   mp.start(); 
42  } 
43  private void makeHandler() 
44  { 
45   handler = new Handler(){ 
46 
47    @Override 
48    public void handleMessage(Message msg) { 
49     switch(msg.what) 
50     { 
51     case FIRE: 
52     { 
53      v.invalidate(); 
54      break; 
55     } 
56     } 
57    } 
58    
59   }; 
60   
61  } 
62  private class MyRunnable extends Runnable {// you had this in the wrong spot... 
63    private boolean doRun = true; 
64    
65    @Override 
66    public void run(){ 
67    while(doRun) 
68     handler.sendEmptyMessage(FIRE); 
69     } 
70   public void stopThread(){ 
71    doRun = false; 
72   } 
73  } 
74  protected void onpause() { 
75   super.onpause(); 
76   mp.stop(); 
77   r.stopThread(); 
78   finish(); 
79  } 
80  protected void onfinish() { 
81   mp.stop(); 
82   r.stopThread(); 
83   finish(); 
84  } 
85   
86  } 

Je reçois une erreur qui runnable ne peut pas être la superclasse. Spécifiquement que le type runnable ne peut pas être la superclasse de MyRunnable; une super-classe doit être une classe. Puis, dans l'onpause et onfinish, il donne l'erreur: La méthode stopThread n'est pas définie pour le type runnable. Cela arrive même lorsque extend est changé en implements.

J'ai aussi essayé:

01 Runnable MyRunnable = new Runnable(){ 
02   
03   
04   private boolean doRun = true; 
05   
06   @Override 
07   public void run(){ 
08    while(doRun) 
09     handler.sendEmptyMessage(FIRE); 
10   } 
11   public void stopThread(){ 
12    doRun = false; 
13   } 
14  } 

J'ai essayé aussi:

private class MyRunnable implements Runnable \\etc 

qui efface la question, mais runnable cause mon

r = new MyRunnable(); 

et

r.stopThread(); 

pour être encore des erreurs qui disent: la stopThread is undefined for the type runnable, and Type mismatch cannot convert from CanvasDrawingActivity.MyRunnable to Runnable.

Quelqu'un peut-il me aider. Je pense que c'est une bonne option pour terminer le thread, mais encore une fois, je reçois des erreurs infranchissables ...

+0

êtes-vous sûr que son onpause ou [onPause()] (http://developer.android.com/reference/android/app/Activity.html#onPause()) se réfèrent également à [this] (http: // stackoverflow.com/questions/1204012/why-isnt-the-thread-stopping) – Reno

+0

Pour une raison quelconque, il aime faire ces minuscules. C'est onPause(), mais la mise en forme a changé cela. – user571866

Répondre

1

Lorsque vous utilisez une classe anonyme, les seules méthodes auxquelles vous pouvez accéder en dehors de la classe elle-même sont celles déclarées dans son supertype. Dans votre cas, n'importe quel code en dehors de la classe peut seulement appeler la méthode run(), puisque c'est tout ce qui est défini pour un Runnable. La solution consiste à déclarer une classe explicite, ce que vous avez essayé de faire avec MyRunnable.

Les messages d'erreur, cependant, suggèrent que vous n'avez pas tout à fait raison. En particulier, l'erreur "incompatibilité de type" indique que MyRunnable n'implémente pas Runnable. Ce message doit provenir d'un code différent de ce que vous avez posté. Aussi, apparemment, quel que soit l'objet que vous essayez d'utiliser pour appeler stopThread, le compilateur n'est connu à ce stade que comme Runnable, pas comme MyRunnable.

Sur une note séparée, une fois que vous avez passé les erreurs du compilateur, vous ne serez pas satisfait de la façon dont cela fonctionne. Vous enverrez des messages FIRE vides aussi vite que le CPU peut les produire. Vous devez ralentir un peu, peut-être en appelant Thread.sleep() avec un délai approprié.

+0

J'ai déclaré r, que j'utilise pour le runnable comme: private MyRunnable r; Donc, il devrait enregistrer comme un myRunnable mais ne le fait pas. Je ne suis pas sûr pourquoi. En ce qui concerne l'ajout de Thread.sleep, est-ce quelque chose comme Thread.sleep (increment) ou: thread.sleep (2000) pour le ralentir. J'utilise ceci pour alterner une couleur sur un écran, que je veux clignoter assez rapidement, mais pas si follement. J'apprécie l'aide et toute autre idée que vous pourriez avoir. – user571866

+0

Je voudrais encore entendre vos opinions sur le thread.sleep et comment l'utiliser de manière appropriée. J'adorerais que ça se passe bien à la porte. – user571866

+0

Thread.sleep (35) mettra la boucle en pause pendant 35 millisecondes. C'est environ 30 images par seconde, ce qui est à la limite de ce que l'œil peut suivre. De nombreuses animations fonctionnent très bien avec 10 fps, ou 100 mSec entre les images. Si vous flashez une couleur, une fois toutes les deux secondes devrait être bien. Vous devrez entourer l'appel pour dormir avec un bloc try/catch pour InterruptedException. Cela est levé si interruption() est appelé sur le thread dormant. –

0

Ce qui suit compile très bien pour moi:

private MyRunnable r; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    r = new MyRunnable();// this needs to create a new MyRunnable 
} 
private class MyRunnable implements Runnable { 

    private boolean doRun = true; 
    @Override 
    public void run() { 
     // do stuff 
    } 
    public void stopThread(){ 
     doRun = false; 
    } 
} 
@Override 
protected void onPause(){ 
    r.stopThread(); 
} 
@Override 
protected void onDestroy() { 
    r.stopThread(); 
} 

Vous devez garder à l'esprit les commentaires de @Ted Hopp en ce qui concerne la performance de cette solution.

+0

Merci de l'avoir posté. C'est pratiquement identique à ce que j'ai dans mon code actuel. Le problème est que j'obtiens ceci: le stopThread est indéfini pour le type runnable, et la différence de type ne peut pas convertir de CanvasDrawingActivity.MyRunnable en Runnable. Je ne suis pas sûr pourquoi le mien ne compile pas ... – user571866

+0

J'ai réarrangé le placement de quelques unes de mes déclarations et POOF cela a fonctionné! Je ne sais pas pourquoi, ils auraient dû travailler là où ils étaient, mais bon, nous sommes en affaires. Merci pour le soutien! – user571866