当我在Debug中运行时,我得到了这个错误数百次,它似乎没有影响程序,但我该如何摆脱它?
我知道它可以追溯到基于其他帖子的SoundPool
09-15 09:03:09.190:ERROR / AudioCache(34):堆大小溢出!需求尺寸:1052672,最大尺寸:1048576
解决方法
对于所有加载的文件,SoundPool的缓冲区大小为1M.因此,当您将太多文件加载到SoundPool时,您可能会收到“堆大小溢出”错误.我也有一个游戏项目的问题,将游戏声音FX加载到SoundPool,解决方案如下:
>在MediaPlayer中播放长/大背景音乐.
>在多个SoundPool实例中播放短声音文件以防止堆错误.多个SoundPools的示例代码:
/** * Multi SoundPool to prevent memory error. */ public class SoundPools { private static final String TAG = "SoundPools"; private static final int MAX_STREAMS_PER_POOL = 15; private List<SoundPoolContainer> containers; public SoundPools() { containers = Collections.synchronizedList(new ArrayList<SoundPoolContainer>()); } public void loadSound(Context context,String id,String file) { Log.d(TAG,"SouldPools load sound " + file); try { for (SoundPoolContainer container : containers) { if (container.contains(id)) { return; } } for (SoundPoolContainer container : containers) { if (!container.isFull()) { container.load(context,id,file); return; } } SoundPoolContainer container = new SoundPoolContainer(); containers.add(container); container.load(context,file); } catch (Exception e) { Log.w(TAG,"Load sound error",e); } } public void playSound(Context context,"SouldPools play sound " + file); try { for (SoundPoolContainer container : containers) { if (container.contains(id)) { container.play(context,file); return; } } for (SoundPoolContainer container : containers) { if (!container.isFull()) { container.play(context,file); return; } } SoundPoolContainer container = new SoundPoolContainer(); containers.add(container); container.play(context,"Play sound error",e); } } public void onPause() { for (SoundPoolContainer container : containers) { container.onPause(); } } public void onResume() { for (SoundPoolContainer container : containers) { container.onResume(); } } private static class SoundPoolContainer { SoundPool soundPool; Map<String,Integer> soundMap; AtomicInteger size; public SoundPoolContainer() { this.soundPool = new SoundPool(MAX_STREAMS_PER_POOL,android.media.AudioManager.STREAM_MUSIC,0); this.soundMap = new ConcurrentHashMap<String,Integer>(MAX_STREAMS_PER_POOL); this.size = new AtomicInteger(0); } public void load(Context context,String file) { try { this.size.incrementAndGet(); soundMap.put(id,soundPool.load(context.getAssets().openFd(file),1)); } catch (Exception e) { this.size.decrementAndGet(); Log.w(TAG,e); } } public void play(Context context,String file) { android.media.AudioManager audioManager = (android.media.AudioManager) context .getSystemService(Context.AUdio_SERVICE); final int streamVolume = audioManager.getStreamVolume(android.media.AudioManager.STREAM_MUSIC); Integer soundId = soundMap.get(id); if (soundId == null) { soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool,int sampleId,int status) { soundPool.play(sampleId,streamVolume,1,1f); } }); try { this.size.incrementAndGet(); soundPool.load(context.getAssets().openFd(file),1); } catch (IOException e) { this.size.decrementAndGet(); Log.w(TAG,"Load/Play sound error",e); } } else { try { soundPool.play(soundId,1f); } catch (Exception e) { Log.w(TAG,e); } } } public boolean contains(String id) { return soundMap.containsKey(id); } public boolean isFull() { return this.size.get() >= MAX_STREAMS_PER_POOL; } public void onPause() { try { soundPool.autoPause(); } catch (Exception e) { Log.w(TAG,"Pause SoundPool error",e); } } public void onResume() { try { soundPool.autoResume(); } catch (Exception e) { Log.w(TAG,"Resume SoundPool error",e); } } } }