心魅 - cocoromi -

半角スペース時々全角

MediaPlayerの状態遷移

音を再生するためのクラスMediaPlayerというのがあるのだが、こいつにたいして送るメッセージはMediaPlayerの状態に応じて変更する必要がある。

状態遷移図がAPIドキュメントに読むのでコーディングするときはにらめっこしながらやりましょう。
MediaPlayer | Android Developers

音を再生するためには

図を初期状態(Idle)の方から見ていくと再生するため(状態Startedに遷移するため)には、MediaPlayer(以下MP)の状態がPreparedになっている必要があることがわかる。


MPのインスタンスを生成する方法は大きく2種類あって、MediaPlayer.createを使うかnewするかが選べる。


さて、MediaPlayer.createの説明をみると以下のようなことが書いてある。
http://developer.android.com/intl/ja/reference/android/media/MediaPlayer.html#create(android.content.Context, android.net.Uri)

On success, prepare() will already have been called and must not be called again.

prepareメソッドはすでに呼んであるから、もう呼んじゃダメよって書いてある。
つまりこの方法でMPのインスタンスを取得するとすでに状態がPreparedまで遷移しているインスタンスを取得できるため、すぐにstartをコールすることができる。


一方で、newした場合はどうなるかというと初期状態のIdleのインスタンスが取得できる。
なのでここから、startをコールするためには、先にsetDataSourceとprepareを呼ぶ必要がある。

DataSourceの再指定

さて、MPのインスタンスを使い回して再生するデータを変更する場合はどうしたらいいだろうか。
また、状態遷移図を確認すると、setDataSouceをコールするためにはMPをIdle状態へと遷移する必要があることがわかる。
Idle状態へはresetをコールすることで遷移できる。


なので、例えば、再生中のMPから別の音声を再生するためには一旦resetをコールした後にsetDataSouceをコールする

IllegalStateException

状態に合わないメソッドをコールすると例外、IllegalStateExceptionが飛んでくる。
開発中にこの例外に出くわしたら、特定の操作で意図しない状態から遷移不可能な状態へと遷移しようとしているということである。


どこかに状態遷移がおかしいところがないかチェックする。


まとめ

MediaPlayerクラスは状態を持っており、コールできるメソッドはその時の状態に依存している。
また、遷移先の状態はAPI ドキュメントの状態遷移図で確認できる。