问题
i have a few functions that have to be implemented synchronously for 3 seconds. i have a sound being played using soundpool, a vibration pattern, and a background animation. all three of them work fine separately. but i am not able to time them properly so that all start together.
these 3 functions need to be called repeatedly after every 15 seconds. and will be stopped on a button click. i tried using something like this, but it doesnt work properly.
myThread = new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while (shouldRun==true) {
try {
mHandler.post(new Runnable() {
@Override
public void run() {
anim();
vibration();
sound();
}
});
mHandler.postDelayed(new Runnable() {
public void run(){
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 3000);
} catch (Exception e) {
// TODO: handle exception
}
}
}// end of outer run()
});
myThread.start();
is this the right way to do it? or is there some other way?
public void vibration(){
int dash = 1000;
int medium_gap = 500;
long[] pattern = { 0, // Start immediately
dash, medium_gap,dash , medium_gap
};
// Only perform this pattern one time (-1 means "do not repeat")
v.vibrate(pattern, -1);
}
linear = (LinearLayout) findViewById(R.id.lay);// this line is after setContentView in onCreate
public void anim(){
drawable.addFrame(new ColorDrawable(Color.RED), 1000);
drawable.addFrame(new ColorDrawable(Color.WHITE), 500);
drawable.setOneShot(false);
linear.setBackgroundDrawable(drawable);
drawable.start();
}
sp = new SoundPool(5, AudioManager.STREAM_NOTIFICATION, 0);
buzzer = sp.load(this, R.raw.buzzer, 0);
public void sound(){
sp.play(buzzer, 1,1, 0, 0, 1); //start alert tone
}
回答1:
Try the following.
myThread= new Thread(new Runnable(){
@Override
public synchronized void run() {
// TODO Auto-generated method stub
Write your stuff..............
....................
}
}).start();
回答2:
Is there really need to implement such function synchronously? Android UI is asynchronous and for good reason. You did not write how did you implement anim, vibration and sound methods. I am not sure they can be implemented this way, especially animation. Drawing in android should be usually done in main thread. If you want to handle application pause, or key events, or cancel your ringing, you should be able to react on incoming events, and your current thread does not allow it.
I suggest you check API how to play a sound and how to vibrate. Then use any event to start action. Start vibrator, start sound playing and begin animation. Use handler to send delayed message after 3 seconds to stop it. Cancel sound play, vibrating, stop redrawing animation. And use handler after 15 seconds from stop to start it again. It seems important to me, where will be background animation and what widget will be used for it? You can do that using SurfaceHolder, but again, unless you NEED to use synchronous code, do not do that.
回答3:
Without seeing all the code I am not sure if any of it needs to be on the UI thread, but probably the animation does. My thought was to have each in its own thread, and just have a play, pause, and release methods. So after 3 seconds tell them all to pause. And then tell them all to play. The animation will have to post something to the UI thread from its run method though. One other problem ... depending on how closely synchronized you need them this may be problematic because there may be a significant delay in playing sounds on older android versions.
EDIT: Can you also update your question to just give a little more detail of what goes wrong as in, do they all start around the same time, play one after the other or something else.
Here is a stab at some of the code. If you add the below code to your class, then create and start the threads somewhere sensible (like the view creation)
Sound s = new Sound();
s.start();
Vibrate vi = new Vibrate(v);
vi.start();
and set their release to true in your onStop() method. Finally, in run method of your handler instead of:
anim();
vibration();
sound();
have:
s.play = true;
vi.play = true;
anim();
// classes to add
class Sound extends Thread
{
public boolean play = false;
SoundPool sp;
int buzzer;
public boolean released = false;
public Sound()
{
sp = new SoundPool(5, AudioManager.STREAM_NOTIFICATION, 0);
buzzer = sp.load(this, R.raw.buzzer, 0);
}
public void run()
{
while (!released)
{
if (play)
{
sp.play(buzzer, 1,1, 0, 0, 1); //start alert tone
play = false;
}
else
{
try
{
Thread.sleep(5);
}
catch (Exception ex) {}
}
}
// release the sound pool
}
}
class Vibrate extends Thread
{
public boolean play = false;
public boolean released = false;
int dash = 1000;
int medium_gap = 500;
Vibrator v;
long[] pattern = { 0, // Start immediately
dash, medium_gap, dash , medium_gap };
public Vibrate(Vibrator v)
{
this.v = v;
}
public void run()
{
while (!released)
{
if (play)
{
// Only perform this pattern one time (-1 means "do not repeat")
v.vibrate(pattern, -1);
play = false;
}
else
{
try
{
Thread.sleep(5);
}
catch (Exception ex) {}
}
}
}
}
来源:https://stackoverflow.com/questions/15335791/perform-functions-synchronously