5

当用户点击 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;
        });
    }
}
4

1 回答 1

6

不要在那里使用InvokeOnMainThread,因为InvokeOnMainThread在返回给调用者之前等待输入操作完成。这就是为什么您的 Dispose 调用在您仍然在调用内部时发生的原因KillAudioPlayer,在HandleAudioFinished回调内部。

而是使用BeginInvokeOnMainThread,它将安排你的清理操作在主线程上发生,但会立即返回到你的 KillAudioPlayer 函数,让它完成。

于 2013-05-24T20:50:14.687 回答