0

I've written a AsyncTask:

public class AudioTransition extends AsyncTask <Void, Void, MediaPlayer>
{   
    private int goalID;
    private int milliseconds;
    private MediaPlayer tempPlayer;

    AudioTransition(int ID, int Milliseconds)
    {
        goalID = ID;
        milliseconds = (int)(((float)Milliseconds)/100);
    }

    @Override
    protected void onPreExecute()
    {
       tempPlayer = MediaPlayer.create(context, goalID);
       tempPlayer.setVolume(0, 0);
       tempPlayer.setLooping(true);
       tempPlayer.start();
    }

    @Override
    protected MediaPlayer doInBackground(Void... arg0) {

        for (int i = 0; i < 100; i++)
        {
            value = i;

            publishProgress();
            try {
                Thread.sleep(milliseconds);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (!player.isPlaying())
                tempPlayer.pause();
        }

        return tempPlayer;
    }

    @Override
    protected void onProgressUpdate(Void... v) {
        super.onProgressUpdate(v);
        player.setVolume(100-value, 100-value);
        tempPlayer.setVolume(value, value);
    }


    @Override
    protected void onPostExecute( MediaPlayer result )  {
          super.onPostExecute(result);
          player.reset();
          player = tempPlayer;
          player.setVolume(100,100);
          transitioning = false;
    }
}

But the volume doesn't fade out. It just starts both tracks, then stops. The MediaPlayers are not updated until doInBackground completes. How can I make the MediaPlayers get updated within this type of background worker? It seems like the publishProgress() thing should work.

Nathan Tornquist
  • 6,468
  • 10
  • 47
  • 72

1 Answers1

1

Oh lord. Dont be sleeping threads inside of AsyncTask! You are completely misusing AsyncTask. You couldn't think of another way to do a timer type thing, so you're latching onto the idea of publishprogress from AsyncTask (which doesn't even work how I think you think it works) even though AsyncTask should be used for one thing and one thing only: doing heavy work off of the main (UI) thread.

If you just wanted to fade the volume out then use something like this: (this goes somewhere outside of any method).

 private Runnable VolumeFadeRunnable = new Runnable() {
        @Override
        public void run() {
                volume--;
             player.setVolume(volume, volume);
                 if(volume>0)
               handler.postDelayed(this, 1000);
                 else
                   handler.removeCallbacks(this);
        }
    };

just initialize your handler as a field inside of onCreate or whatever and make sure that and the counter variable are visible inside of that runnable.

LuxuryMode
  • 33,401
  • 34
  • 117
  • 188
  • I'm getting an error about inserting a ; to complete the field declaration. I added one after the last } but the error still exists. Is that an eclipse mistake, or do I need another somewhere? – Nathan Tornquist Jul 24 '12 at 20:49
  • Also, if I move away from asynctask I can't create a second player as easily. I need to maintain two MediaPlayers at all times for the transition to work. – Nathan Tornquist Jul 24 '12 at 20:50
  • Things can get whacky with two mediaplayers, but theres no reason you can create two of them without multithreading like this. Simply have to separate media players and prepare them asynchronously. Don't use the MediaPlayer#create convenience. As for my code, I'll update that in a second. – LuxuryMode Jul 24 '12 at 20:55
  • What's wrong with MediaPlayer.create()? It seems to work well. And can you explain what is so wrong about my original logic? I'd like to avoid making the same mistakes again. – Nathan Tornquist Jul 24 '12 at 21:00
  • Nothing's "wrong" with it, you just have less control and if I'm not mistaken it doesn't prepare the player asynchronously, but I could be wrong. – LuxuryMode Jul 24 '12 at 21:02
  • How do I prepare the player asynchronously? If you could provide a link to valid logic or an example that would be great. I'm getting confused between which type of worker to use, and the way services and everything works together. – Nathan Tornquist Jul 24 '12 at 21:03
  • Take a look at the "random music player" sample inside of your sdk directory at /platforms//samples/ if its not there then open the SDK manager and download the samples. That provides a good example of using a Service and how to handle all of the lifecyle stuff of a media player. – LuxuryMode Jul 24 '12 at 21:12
  • Okay, I've been testing that code you provided. I put in a LogCat debug tag and can see the volume integer going down. The actual volume isn't changing though. Shouldn't a runnable let everything update just fine? – Nathan Tornquist Jul 25 '12 at 14:53
  • --Nevermind I was using the wrong range of values for volume. Thanks! – Nathan Tornquist Jul 25 '12 at 15:02