0

3 秒間同期的に実装する必要がある関数がいくつかあります。サウンドプール、振動パターン、背景アニメーションを使用してサウンドを再生しています。3 つすべてが個別に正常に動作します。しかし、すべてが一緒に始まるように適切にタイミングを合わせることができません。

これら 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

すべてのコードを確認しないと、UI スレッドに必要なコードがあるかどうかわかりませんが、おそらくアニメーションには必要です。私が考えたのは、それぞれを独自のスレッドに配置し、再生、一時停止、および解放のメソッドだけを用意することでした。そのため、3 秒後に全員に一時停止するよう伝えます。そして、みんなで遊ぶように言います。ただし、アニメーションは run メソッドから UI スレッドに何かを送信する必要があります。もう1つの問題...必要な同期の程度によっては、古い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) {}
            }
        }
    }
}
于 2013-03-11T10:47:12.313 に答える
0

そのような関数を同期的に実装する必要は本当にありますか? Android UI は非同期であり、正当な理由があります。アニメーション、バイブレーション、サウンドのメソッドをどのように実装したかを書いていません。特にアニメーションなど、この方法で実装できるかどうかはわかりません。Android での描画は通常、メイン スレッドで行う必要があります。アプリケーションの一時停止やキー イベントを処理したり、呼び出し音をキャンセルしたりしたい場合は、着信イベントに反応できる必要がありますが、現在のスレッドでは許可されていません。

音の鳴らし方やバイブレーションの仕方はAPIで確認することをお勧めします。次に、任意のイベントを使用してアクションを開始します。バイブレーターを開始し、サウンドの再生を開始し、アニメーションを開始します。ハンドラーを使用して、3 秒後に遅延メッセージを送信し、それを停止します。サウンド再生、バイブレーションをキャンセルし、アニメーションの再描画を停止します。そして、停止から 15 秒後に handler を使用して、再度開始します。バックグラウンドアニメーションはどこにあり、どのウィジェットが使用されるのでしょうか? SurfaceHolder を使用してそれを行うことができますが、同期コードを使用する必要がない限り、そうしないでください。

于 2013-03-11T10:46:28.803 に答える
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 に答える