Usando Media Player do Android Evitando Sobrecarga de Recursos do Sistema

Fala pessoal, hoje venho com meu primeiro post sobre Java e desenvolvimento mobile para Android.

Tenho estudado um pouco sobre Android ultimamente e daqui pra frente irei compartilhar algumas dicas que podem ser úteis.

Começando então, vamos falar da classe MediaPlayer. Ela serve para controlar e executar arquivos de áudios, vídeos e streams.

Um "simples" (e errado) uso dessa classe seria:

1
2
3
4
5
6
7
8
9
import android.media.MediaPlayer;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.meu_som);
    mp.start();
}

Na linha 7, criamos uma nova instância da classe MediaPlayer dizendo que o recurso (nesse caso, o áudio do tipo raw) a ser reproduzido será o arquivo meu_som que se encontra na pasta res/raw/meu_som (seguindo a convenção do Android).

Na linha 8 simplesmente chamamos o método play responsável por reproduzir o recurso.

O código acima pode até parecer legal, mas não é..

Cenário

Nosso objetivo aqui é aprender como executar um recurso multimídia esporadicamente de maneira não obstrutiva, como exemplo, vamos supor que você precise reproduzir um som ao clique de um botão, ou qualquer outro evento como esse..

Se você está querendo deixar um áudio de fundo na sua aplicação, talvez esse post não ajude muito, pois você precisa aprender como usar um serviço com MediaPlayer.

Entrando no Cenário

Tendo o cenário descrito acima, vamos dizer que temos o seguinte layout:

<LinearLayout android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/main_layout"
        android:orientation="vertical">

  <Button android:text="@string/my_button"
          android:layout_height="wrap_content"
          android:layout_gravity="center"
            android:layout_width="160dp"
            android:onClick="playAudio"/>
</LinearLayout>

Nesse linear layout temos apenas um botão, onde ao clicar chamamos o método playSound de nossa activity.

Veja a implementação desse método em nossa activity:

public void playAudio(View view){
  MediaPlayer mp = MediaPlayer.create(this, R.raw.meu_som);
  mp.start();
}

Assim como no primeiro exemplo, no trecho acima, a cada clique no botão estamos criando uma instância da classe MediaPlayer e reproduzindo o áudio.

Só que veja o problema ai.. Cada vez que o usuário clicar no botão, criamos uma nova variável e ocupamos recursos do sistema sem necessidade (isso é pouco, ainda tem mais).

Isso poderia ser melhorado, veja:

public MediaPlayer mp = null;

public void playAudio(View view){
  mp = MediaPlayer.create(this, R.raw.meu_som);
  mp.start();
}

Agora criamos uma única variável mp em nossa aplicação e ao rodar o método do clique preenchemos ela com uma instância da classe MediaPlayer.

Isso pode parecer bom, mas ainda podemos devemos melhorar.

Se você clicar várias vezes seguidas no botão, a classe MediaPlayer ficará sobrecarregada e não irá mais reproduzir som (eu disse que tinha mais)..

A documentação oficial do Android recomenda que seja implementada uma descarga da classe MediaPlayer para evitar que recursos do sistema sejam desperdiçados:

mp.release();
mp = null;

Precisamos adicionar o trecho acima após a reprodução do arquivo, mas isso não irá funcionar:

public void playAudio(View view){
  mp = MediaPlayer.create(this, R.raw.meu_som);
  mp.start();
  mp.release();
  mp = null;
}

Acima, tentamos liberar os recursos após o método start, mas isso faria com que o arquivo não fosse reproduzido.

A Solução

Por fim chegamos na solução, o ideal para conseguirmos o que desejamos de uma forma legal, seria assim:

public MediaPlayer mp = null;

public void playAudio(View view){
  mp = MediaPlayer.create(this, R.raw.meu_som);
  mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
    public void onCompletion(MediaPlayer mp) {
      mp.stop();
      mp.release();
      mp = null;
    }
  });
  mp.start();
}

O que fizemos aqui foi criar um evento on completion em nossa instância mp, assim, toda vez que o arquivo acabar de ser reproduzido, liberamos recursos do sistema e também ganhamos a possibilidade de reprodução múltipla sem travar.

Essa foi a dica de hoje. O que você achou?

Até mais.

Written on March 29, 2013

Share: