From f31895b095603acf1331fcd52be2c6ed483601e8 Mon Sep 17 00:00:00 2001 From: Nathan Broadbent Date: Mon, 8 May 2017 20:07:17 +0700 Subject: [PATCH] Fix callback crashes - Guarantee that the RN callback is only ever called once (#168) * Make sure the RN callback is only ever called once * Fix callback crash on Windows --- RNSound/RNSound.m | 13 +++++++------ .../main/java/com/zmxv/RNSound/RNSoundModule.java | 8 ++++++++ windows/RNSoundModule/RNSoundModule/RNSound.cs | 3 +++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/RNSound/RNSound.m b/RNSound/RNSound.m index de0c9f27..b3ededfc 100644 --- a/RNSound/RNSound.m +++ b/RNSound/RNSound.m @@ -44,12 +44,13 @@ -(NSString *) getDirectory:(int)directory { -(void) audioPlayerDidFinishPlaying:(AVAudioPlayer*)player successfully:(BOOL)flag { NSNumber* key = [self keyForPlayer:player]; - if (key != nil) { - @synchronized(key) { - RCTResponseSenderBlock callback = [self callbackForKey:key]; - if (callback) { - callback(@[@(flag)]); - } + if (key == nil) return; + + @synchronized(key) { + RCTResponseSenderBlock callback = [self callbackForKey:key]; + if (callback) { + callback(@[@(flag)]); + [[self callbackPool] removeObjectForKey:key]; } } } diff --git a/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java b/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java index d5225274..f5541f49 100644 --- a/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java +++ b/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java @@ -87,16 +87,24 @@ public void play(final Integer key, final Callback callback) { return; } player.setOnCompletionListener(new OnCompletionListener() { + boolean callbackWasCalled = false; + @Override public synchronized void onCompletion(MediaPlayer mp) { if (!mp.isLooping()) { + if (callbackWasCalled) return; + callbackWasCalled = true; callback.invoke(true); } } }); player.setOnErrorListener(new OnErrorListener() { + boolean callbackWasCalled = false; + @Override public synchronized boolean onError(MediaPlayer mp, int what, int extra) { + if (callbackWasCalled) return true; + callbackWasCalled = true; callback.invoke(false); return true; } diff --git a/windows/RNSoundModule/RNSoundModule/RNSound.cs b/windows/RNSoundModule/RNSoundModule/RNSound.cs index dc7d37cb..28acd840 100644 --- a/windows/RNSoundModule/RNSoundModule/RNSound.cs +++ b/windows/RNSoundModule/RNSoundModule/RNSound.cs @@ -142,6 +142,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio [ReactMethod] public void play(int key, ICallback callback) { + Boolean callbackWasCalled = false; MediaPlayer player = null; Debug.WriteLine("play()"); @@ -167,6 +168,8 @@ public void play(int key, ICallback callback) player.MediaEnded += delegate { + if (callbackWasCalled) return; + callbackWasCalled = true; Debug.WriteLine("Media Ended"); callback.Invoke(true); };