0

我有一些功能必须同步实现 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
    }
4

3 回答 3

0

试试下面的。

myThread= new Thread(new Runnable(){

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


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

             }
       }).start();
于 2013-03-11T10:22:54.593 回答
0

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

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

于 2013-03-11T10:46:28.803 回答
0

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


编辑:您是否还可以更新您的问题以更详细地说明问题所在,它们是否都在同一时间开始,一个接一个地播放或其他什么。

这是一些代码的刺探。如果您将以下代码添加到您的类中,然后在合理的地方创建并启动线程(如视图创建)

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

并在您的 onStop() 方法中将它们的 release 设置为 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) {}
            }
        }
    }
}
于 2013-03-11T10:47:12.313 回答