perform functions synchronously

对着背影说爱祢 提交于 2019-12-12 03:46:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!