我得到了一些答案,然后前进并尝试了以下内容:
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 }
我收到一个错误,runnable不能是超类。具体来说,runnable类型不能是MyRunnable的超类;超类必须是一个类。
然后在onpause和onfinish中它给出了错误:对于runnable类型,未定义Te方法stopThread。即使将extends更改为implements,也会发生这种情况。
我也尝试过:
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 }
我也试过了:
private class MyRunnable implements Runnable \\etc
清除可运行的问题,但会导致我的
r = new MyRunnable();
和
r.stopThread();
仍然是错误说:
stopThread is undefined for the type runnable, and Type mismatch cannot convert from CanvasDrawingActivity.MyRunnable to Runnable.
任何人都可以帮助我。我觉得这是结束线程的一个很好的选择,但同样,我得到了一些无法弥补的错误......
答案 0 :(得分:1)
当您使用匿名类时,您可以从类外部访问的唯一方法是在其超类型中声明的方法。在您的情况下,类外的任何代码只能调用run()方法,因为这是为Runnable定义的所有代码。解决方案是声明一个显式类,这是你试图用MyRunnable做的。
但是,错误消息表明您没有完全正确。特别是,“类型不匹配”错误表明MyRunnable没有实现Runnable。该消息必须来自与您发布的内容不同的代码。此外,显然,您尝试用来调用stopThread的任何对象在编译器时都只知道为Runnable而不是MyRunnable。
另外,一旦你超越编译器错误,你就不会对它的运行方式感到满意。您将以cpu可以生成它们的速度发送空的FIRE消息。你可能需要稍微降低一点,可能是通过调用Thread.sleep()并适当延迟。
答案 1 :(得分:0)
以下编辑对我来说很好:
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();
}
你应该记住@Ted Hopp关于这个解决方案性能的评论。