android soundpool heapsize overflow

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

I get this error hundreds of times when I run in Debug, it doesn't seem to affect the program, but how do I get rid of it?

I know it can be traced back to the SoundPool based on other posts

09-15 09:03:09.190: ERROR/AudioCache(34): Heap size overflow! req size: 1052672, max size: 1048576

回答1:

SoundPool is hard code the buffer size as 1M for all loaded file. So you probably will get 'heap size overflow' error when you load too much files into SoundPool. I also have this issue on a game project that will load game sound FX into SoundPool and the solution is as follow:

  1. Play long/large background music in MediaPlayer.
  2. Play short sound files in multi SoundPool instances to prevent the heap error. The sample code for multi 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 containers;    public SoundPools() {     containers = Collections.synchronizedList(new ArrayList());   }    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, id, file);     } catch (Exception e) {       Log.w(TAG, "Load sound error", e);     }   }    public void playSound(Context context, String id, String file) {     Log.d(TAG, "SouldPools play sound " + file);     try {       for (SoundPoolContainer container : containers) {         if (container.contains(id)) {           container.play(context, id, file);           return;         }       }       for (SoundPoolContainer container : containers) {         if (!container.isFull()) {           container.play(context, id, file);           return;         }       }       SoundPoolContainer container = new SoundPoolContainer();       containers.add(container);        container.play(context, id, file);     } catch (Exception e) {       Log.w(TAG, "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 soundMap;     AtomicInteger size;      public SoundPoolContainer() {       this.soundPool = new SoundPool(MAX_STREAMS_PER_POOL, android.media.AudioManager.STREAM_MUSIC, 0);       this.soundMap = new ConcurrentHashMap(MAX_STREAMS_PER_POOL);       this.size = new AtomicInteger(0);     }      public void load(Context context, String id, 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, "Load sound error", e);       }     }      public void play(Context context, String id, 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, streamVolume, 1, 0, 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, streamVolume, streamVolume, 1, 0, 1f);         } catch (Exception e) {           Log.w(TAG, "Play sound error", 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);       }     }   }  } 



回答2:

Maybe your media resource is too big for playing with soundpool. Soundpool only plays short sound effects. On the Soundpool API there is no specification about the maximum of a resource for playing with soundpool, but if You use it, play just short sound effects like, for example, a short explosion in a shooter game. If this is Your problem, You should use MediaPlayer for playing your sounds.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!