Question

I have an Android service that is creating quite a bug for me. It is a runnable with an if/else statement. Basically, I need it to continuously run a check and execute the if continuously. It does this flawlessly. I need it the execute the else just one time until it detects the if again.

The problem I have is that it runs the else process in a loop also. How can I make the else statement run once while still detecting for the if?

Heres a code example...

         if(mTimer != null) {
            mTimer.cancel();
        } else {
            // recreate new
            mTimer = new Timer();
        }
        // schedule task
        mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
    }



    class TimeDisplayTimerTask extends TimerTask {

        @Override
        public void run() {
            // run on another thread
            mHandler.post(new Runnable() {

                @Override
                public void run() {
                    // display toast

                    if(musicActive) {
                     // Set Ringer to vibrate

                  } else {
                        // Set Ringer to Normal


                  }
                }

            });
        }           

the problem is that when the service is running and music isnt detected, people are unable to change their ringer setting because my app is still holding it inside the service. If I leave the }else{ empty, I get my desired result, but I need it to run that process one time to set the ringer to normal. I just dont need it to set the ringer to normal once every second.

Était-ce utile?

La solution

The simplest way is just to remember, something like this:

 boolean lastWasElse = false;


 mHandler.post(new Runnable() {

       @Override
       public void run() {

           if(true) {
                //  do this
                lastWasElse = false;
           } else if (!lastWasElse) {
                  // do once and then loop again, but if the answer is still "else" then skip this line.
                lastWasElse = true;
           }
       }

The trouble is where you store the lastWasElse variable - since you are constantly creating new runnables. You need to store one copy of that variable somewhere centrally and check it each time the task runs...

...or re-use the same Runnable constantly instead of creating new ones and store the variable inside the Runnable.

Autres conseils

I don't really see why you cant set ringer mode just once, before you start your timer loop :

myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
// and then
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);

More comments:

Your TimerTask#run alread runs in a background thread, you could do your job here without delegating to Handler's thread, which I suppose is the UI thread in your case. In that case make sure you don't have anything potentially blocking UI here :

if(musicActive) {
    // do this
    // but watch out not to do blocking operations
}

Otherwise, you could only post your // Display Toast to Handler's UI thread and do your if / else in TimerTask#run() directly.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top