当用户在UITableView中点击一行时,我正在使用AVAudioPlayer播放声音。如果他们再次点击该行,则播放器停止并被释放,如果他们听完该歌曲直到它完成,那么FinshedPlaying处理程序将处理该播放器。
我遇到的问题是,当我尝试在FinishedPlaying处理程序中处理播放器时,我收到错误消息:
System.ObjectDisposedException:播放器对象是Dispose()d 在回调期间,这已经破坏了程序的状态
这是代码,知道我做错了什么?
void HandleOnRequestPlayMusic (object sender, UrlEventArgs e)
{
var url = Utils.UrlFromString(e.Url);
string oldUrl = "";
if (musicPlayer != null)
{
oldUrl = musicPlayer.Url.AbsoluteString;
KillAudioPlayer(); // no problems killing the audio player from here
}
if (oldUrl != url.AbsoluteString)
{
musicPlayer = AVAudioPlayer.FromUrl(url);
musicPlayer.FinishedPlaying += HandleAudioFinished;
musicPlayer.Play();
}
}
void HandleAudioFinished (object sender, AVStatusEventArgs e)
{
KillAudioPlayer(); // killing audio player from here causes app to crash
}
void KillAudioPlayer ()
{
if (musicPlayer != null)
{
InvokeOnMainThread(() => {
musicPlayer.Stop();
musicPlayer.FinishedPlaying -= HandleAudioFinished;
musicPlayer.Dispose();
musicPlayer = null;
});
}
}
答案 0 :(得分:5)
不要在那里使用InvokeOnMainThread,因为InvokeOnMainThread
在返回其调用者之前等待输入操作完成。这就是为什么当你仍然在KillAudioPlayer
回调中的HandleAudioFinished
来电时,你的处理呼叫正在发生。
而是使用BeginInvokeOnMainThread,它将在主线程上安排清理操作,但会立即返回到KillAudioPlayer函数,允许它完成。