最后的部分是剩下的关于音乐实现的部分,与最先给出的抽象接口/类对应,于音乐有关的三个类分别对应Audio,Music,Sound的具体实现,Audio是两者的统一管理,程序通过Audio来取得Music或Sound,下面是3者的具体实现
public class AndroidAudio implements Audio {
AssetManager assets;
SoundPool soundPool;
public AndroidAudio(Activity activity){
activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
this.assets=activity.getAssets();
this.soundPool=new SoundPool(20,AudioManager.STREAM_MUSIC,0);
}
@Override
public Music newMusic(String filename) {
try {
AssetFileDescriptor assetDescriptor=assets.openFd(filename);
return new AndroidMusic(assetDescriptor);
} catch (IOException e) {
throw new RuntimeException("Couldn't load music '"+filename+"'");
}
}
@Override
public Sound newSound(String filename) {
try{
AssetFileDescriptor assetDescriptor=assets.openFd(filename);
int soundId=soundPool.load(assetDescriptor, 0);
return new AndroidSound(soundPool,soundId);
} catch (IOException e) {
throw new RuntimeException("Couldn't load sound '"+filename+"'");
}
}
}
public class AndroidSound implements Sound {
int soundId;
SoundPool soundPool;
public AndroidSound(SoundPool soundPool, int soundId){
this.soundId=soundId;
this.soundPool=soundPool;
}
@Override
public void dispose() {
soundPool.unload(soundId);
}
@Override
public void play(float volume) {
soundPool.play(soundId, volume, volume, 0, 0, 1);
}
}
public class AndroidMusic implements Music, OnCompletionListener {
MediaPlayer mediaPlayer;
boolean isPrepared =false;
public AndroidMusic(AssetFileDescriptor assetDescriptor){
mediaPlayer=new MediaPlayer();
try {
mediaPlayer.setDataSource(assetDescriptor.getFileDescriptor(),assetDescriptor.getStartOffset(),assetDescriptor.getLength());
mediaPlayer.prepare();
isPrepared=true;
mediaPlayer.setOnCompletionListener(this);
} catch (Exception e) {
throw new RuntimeException("Couldn't load music");
}
}
@Override
public void dispose() {
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.release();
}
@Override
public boolean isLooping() {
return mediaPlayer.isLooping();
}
@Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
@Override
public boolean isStopped() {
return !isPrepared;
}
@Override
public void pause() {
}
@Override
public void play() {
if(mediaPlayer.isPlaying()){
return;
}
try{
synchronized (this) {
if(!isPrepared){
mediaPlayer.prepare();
}
mediaPlayer.start();
}
} catch (IllegalStateException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
@Override
public void setLooping(boolean looping) {
mediaPlayer.setLooping(looping);
}
@Override
public void setVolume(float volume) {
mediaPlayer.setVolume(volume, volume);
}
@Override
public void stop() {
mediaPlayer.stop();
synchronized (this) {
isPrepared=false;
}
}
@Override
public void onCompletion(MediaPlayer arg0) {
synchronized (this) {
isPrepared=false;
}
}
}