场景
①
...
<T extends Disposable> T getAssets(String fileName, Class<T> clazz) {
if (!manager.isLoaded(fileName, clazz)) {
Gdx.app.log(tag, clazz.getSimpleName() + " 资源未加载 " + fileName);
manager.load(fileName, clazz);
manager.finishLoadingAsset(fileName);
}
return manager.get(fileName, clazz);
}
...
②
...
public Sound getSound(String fileName) {
return getAssets(fileName, Sound.class);
}
...
③
...
getSound("xxxxxxxxxxx").play();
...
环境
gdx 版本 1.9.2
- pc 平台可以正常播放
- android 平台(android 7.0)在程序首次加载该 sound 时不会播放声音。
原因
查看 android 日志,会打印如下日志
05-23 18:34:16.104 6469 6489 W SoundPool: sample 4 not READY
android 部分代码 Sound com.badlogic.gdx.backends.android.AndroidAudio.newSound(FileHandle file)
@Override
public Sound newSound (FileHandle file) {
if (soundPool == null) {
throw new GdxRuntimeException("Android audio is not enabled by the application config.");
}
AndroidFileHandle aHandle = (AndroidFileHandle)file;
if (aHandle.type() == FileType.Internal) {
try {
AssetFileDescriptor descriptor = aHandle.getAssetFileDescriptor();
AndroidSound sound = new AndroidSound(soundPool, manager, soundPool.load(descriptor, 1));
descriptor.close();
return sound;
} catch (IOException ex) {
throw new GdxRuntimeException("Error loading audio file: " + file
+ "\nNote: Internal audio files must be placed in the assets directory.", ex);
}
} else {
try {
return new AndroidSound(soundPool, manager, soundPool.load(aHandle.file().getPath(), 1));
} catch (Exception ex) {
throw new GdxRuntimeException("Error loading audio file: " + file, ex);
}
}
}
使用 AssetManager 管理器加载 sound 本质上也是调用上面代码
追踪 AndroidSound 的 paly 代码后得出结论:
实例化 AndroidSound 完成的时候,其实 android 的音频解码器还未解码加载完成该 sound 时就调用 play 方法了。
解决
public void seriousPlay(Sound sound){
while (sound.play() ==-1 ) {
// do nothing
}
}