I was following a tutorial to integrate SoundPool into my app, and this is the code which was given in the tutorial:
package com.example.soundpoolexample;
i
I tried iTech's semaphore solution and it didn't work. The application sits there waiting forever.
onCreate is called with the main thread. This thread creates the sound pool, starts the loading of the sound, and then parks itself waiting for the loading to complete. Seems like it should work, right?
After some investigation, I found that SoundPool has the undocumented behavior of always running onLoadComplete with the main thread using the Looper/Handler mechanism. Since the main thread is parked, it cannot receive that event, and the application hangs.
We can see how this works in the Android source code in SoundPool.java:
public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)
{
synchronized(mLock) {
if (listener != null) {
// setup message handler
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(mProxy, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(mProxy, looper);
} else {
mEventHandler = null;
}
} else {
mEventHandler = null;
}
mOnLoadCompleteListener = listener;
}
}
This shows that it uses the main thread looper by default unless you have a looper of your own set up.
The simplest solution is to run the entire sound loading procedure in a new thread and return from the main thread immediately. You can then use the main thread to show a loading screen if necessary. When the sound is loaded, the main thread is free to receive the onLoadComplete call and signal the sound loading thread. The sound loading thread can wait for that signal with a semaphore or wait/notify on a shared Object.