我正在尝试通过创建多个线程来实现简单的音频延迟效果。每个线程都实例化一个SoundPool对象,从而播放声音的副本。通过使用Thread.sleep(delayTime)获得延迟效果,其中delayTime被方便地设置为每个线程的不同值,以便延迟声音再现。我将创建的SoundPool对象存储到一个数组中,以便以后操作它们(例如更改一些参数值)。
我试图以两种方式实现线程(作为一个简单的线程或实现Runnable),并且两个实现都会在线程设置后访问SoundPool对象时出现问题,这可能是由于通过其创建线程锁定对象。但是,共享一个简单变量时似乎没有出现这些问题。
简单地说,我想公开访问一个被线程操纵的对象,我不知道如何释放线程对它的锁定。
这是代码。
第一次实施 第一个实现成功创建了效果,但无法从线程外部访问SoundPool对象。例如,我创建了一个按钮,其按钮会暂停播放所有声音副本。
public class MainActivity extends Activity implements OnClickListener {
public SoundPool soundCopies[];
int soundCopiesNumber = 6;
double delayTimes[];
double volumes[];
int soundIds[];
int streamIds[];
int copyIndex = 0;
long delayTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
//other code
final SoundPool[] soundCopies = new SoundPool[6];
final int[] soundIds = new int[6];
final int[] streamIds = new int[6];
final double[] volumes = new double[6];
double[] delayTimes = new double[6];
//filling volumes[] and delayTimes[] with convenient values and other code
//create a thread for each sound copy
for (int i = 0; i<soundCopiesNumber; i++ ){
copyIndex = i;
delayTime = (long)delayTimes[i];
new Thread(){
public void run(){
try {
Thread.sleep(delayTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
//create a SoundPool
soundCopies[copyIndex] = new SoundPool(6, AudioManager.STREAM_MUSIC, 0);
//other code related to the SoundPool managament, setting parameters
//such as volume and playing the sound
}.start();
}
//managing the button click in order to stop playing
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
//other code
case R.id.delayStop:
for (int i = 0; i<soundCopiesNumber; i++ ){
try {
//pause the playing of each sound
soundCopies[i].pause(streamIds[i]);
} catch (Exception e){
e.printStackTrace();
}
}
break;
default:
break;
}
}
}
点击按钮产生的异常是:
W/System.err(31075): java.lang.NullPointerException
W/System.err(31075): at com.example.soundpooltest.MainActivity.onClick(MainActivity.java:174)
W/System.err(31075): at android.view.View.performClick(View.java:4424)
W/System.err(31075): at android.view.View$PerformClick.run(View.java:18383)
W/System.err(31075): at android.os.Handler.handleCallback(Handler.java:733)
W/System.err(31075): at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err(31075): at android.os.Looper.loop(Looper.java:137)
W/System.err(31075): at android.app.ActivityThread.main(ActivityThread.java:4998)
W/System.err(31075): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(31075): at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err(31075): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
W/System.err(31075): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
W/System.err(31075): at dalvik.system.NativeStart.main(Native Method)
第二个实现第二个实现使用Runnable创建一个线程数组,但它们甚至不访问在onCreate方法中实例化的soundCopies数组(即在主线程上)。如果我的第一个实现对于我的目的是不可行的,我也会发布该代码。
提前致谢。