同步执行功能

时间:2013-03-11 10:06:01

标签: android thread-synchronization

我有一些必须同步实现3秒的功能。我使用soundpool,振动模式和背景动画播放声音。他们三个都分别工作得很好。但我无法正确计时,以便一起开始。

这些3个功能需要在每15秒后重复调用一次。并将在按钮单击时停止。我尝试使用这样的东西,但它无法正常工作。

 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();

这是正确的方法吗?或者还有其他方式吗?

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
    }

3 个答案:

答案 0 :(得分:0)

请尝试以下操作。

myThread= new Thread(new Runnable(){

           @Override
           public synchronized void run() {
                // TODO Auto-generated method stub


             Write your stuff..............
             ....................

             }
       }).start();

答案 1 :(得分:0)

是否真的需要同步实现这样的功能? Android UI是异步的,有充分的理由。你没有写过如何实现动画,振动和声音方法。我不确定它们是否可以通过这种方式实现,尤其是动画。在android中绘图通常应该在主线程中完成。如果您想处理应用程序暂停或键事件或取消振铃,您应该能够对传入的事件作出反应,并且您当前的线程不允许它。

我建议您检查API如何播放声音以及如何振动。然后使用任何事件开始行动。启动振动器,开始播放声音并开始动画。使用处理程序在3秒后发送延迟消息以停止它。取消声音播放,振动,停止重绘动画。并在停止15秒后使用处理程序再次启动它。这对我来说似乎很重要,背景动画和将使用哪个小部件?你可以使用SurfaceHolder来做到这一点,但除非你需要使用同步代码,否则不要这样做。

答案 2 :(得分:0)

在没有看到所有代码的情况下,我不确定它是否需要在UI线程中,但可能是动画。我的想法是让每个都在自己的线程中,并且只有一个播放,暂停和释放方法。所以3秒后告诉他们所有人都要暂停。然后告诉他们所有人都要玩。但是,动画必须从其run方法向UI线程发布内容。另一个问题......取决于你需要它们的同步程度,这可能会有问题,因为在较旧的Android版本上播放声音可能会有很大的延迟。


编辑:你能否更新你的问题,只是更详细地说明出现了什么问题,它们都是在同一时间开始,一个接一个地播放或者其他什么。

这是对某些代码的抨击。如果您将以下代码添加到您的类中,那么创建并启动某些合理的线程(如视图创建)

Sound s = new Sound();
s.start();
Vibrate vi = new Vibrate(v);
vi.start();

并在onStop()方法中将其版本设置为true。最后,在处理程序的run方法而不是:

anim();
vibration();
sound();

有:

s.play = true;
vi.play = true;
anim();

//要添加的类

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) {}
            }
        }
    }
}