diff --git a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt
index b2409a0..4491bad 100644
--- a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt
+++ b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt
@@ -18,9 +18,11 @@ import com.doublesymmetry.trackplayer.utils.RejectionException
 import com.facebook.react.bridge.*
 import com.google.android.exoplayer2.DefaultLoadControl.*
 import com.google.android.exoplayer2.Player
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.MainScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 import timber.log.Timber
 import java.util.*
 import javax.annotation.Nonnull
@@ -169,8 +171,12 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
             return
         }
 
+        val bundledData = Arguments.toBundle(data)
+        val androidOptions = bundledData?.getBundle(MusicService.ANDROID_OPTIONS_KEY)
+        val allowBackgroundSetup = androidOptions?.getBoolean("allowBackgroundSetup") ?: false
+
         // prevent crash Fatal Exception: android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && AppForegroundTracker.backgrounded) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && AppForegroundTracker.backgrounded && !allowBackgroundSetup) {
             promise.reject(
                 "android_cannot_setup_player_in_background",
                 "On Android the app must be in the foreground when setting up the player."
@@ -179,7 +185,6 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
         }
 
         // Validate buffer keys.
-        val bundledData = Arguments.toBundle(data)
         val minBuffer =
             bundledData?.getDouble(MusicService.MIN_BUFFER_KEY)?.toMilliseconds()?.toInt()
                 ?: DEFAULT_MIN_BUFFER_MS
@@ -251,7 +256,7 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
     }
 
     @ReactMethod
-    fun updateOptions(data: ReadableMap?, callback: Promise) = scope.launch {
+    fun updateOptions(data: ReadableMap?, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         val options = Arguments.toBundle(data)
@@ -262,13 +267,16 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
 
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun add(data: ReadableArray?, insertBeforeIndex: Int, callback: Promise) = scope.launch {
+    fun add(data: ReadableArray?, insertBeforeIndex: Int, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         try {
-            val tracks = readableArrayToTrackList(data);
+            // Track conversion is O(queue) work (Bundle parsing, Uri resolution) —
+            // keep it off the main thread so long queues don't freeze the UI/ANR.
+            val tracks = withContext(Dispatchers.Default) { readableArrayToTrackList(data) };
             if (insertBeforeIndex < -1 || insertBeforeIndex > musicService.tracks.size) {
                 callback.reject("index_out_of_bounds", "The track index is out of bounds")
                 return@launch
@@ -283,9 +291,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
             rejectWithException(callback, exception)
         }
     }
+    }
 
     @ReactMethod
-    fun load(data: ReadableMap?, callback: Promise) = scope.launch {
+    fun load(data: ReadableMap?, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         if (data == null) {
             callback.resolve(null)
@@ -299,16 +308,18 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
             callback.reject("invalid_track_object", "Track was not a dictionary type")
         }
     }
+    }
 
     @ReactMethod
-    fun move(fromIndex: Int, toIndex: Int, callback: Promise) = scope.launch {
+    fun move(fromIndex: Int, toIndex: Int, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         musicService.move(fromIndex, toIndex)
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun remove(data: ReadableArray?, callback: Promise) = scope.launch {
+    fun remove(data: ReadableArray?, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         val inputIndexes = Arguments.toList(data)
         if (inputIndexes != null) {
@@ -329,9 +340,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
         }
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun updateMetadataForTrack(index: Int, map: ReadableMap?, callback: Promise) =
+    fun updateMetadataForTrack(index: Int, map: ReadableMap?, callback: Promise) {
         scope.launch {
             if (verifyServiceBoundOrReject(callback)) return@launch
 
@@ -346,9 +358,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
                 callback.resolve(null)
             }
         }
+        }
 
     @ReactMethod
-    fun updateNowPlayingMetadata(map: ReadableMap?, callback: Promise) = scope.launch {
+    fun updateNowPlayingMetadata(map: ReadableMap?, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         if (musicService.tracks.isEmpty())
@@ -362,9 +375,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
 
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun clearNowPlayingMetadata(callback: Promise) = scope.launch {
+    fun clearNowPlayingMetadata(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         if (musicService.tracks.isEmpty())
@@ -373,17 +387,19 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
         musicService.clearNotificationMetadata()
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun removeUpcomingTracks(callback: Promise) = scope.launch {
+    fun removeUpcomingTracks(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.removeUpcomingTracks()
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun skip(index: Int, initialTime: Float, callback: Promise) = scope.launch {
+    fun skip(index: Int, initialTime: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.skip(index)
@@ -394,9 +410,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
 
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun skipToNext(initialTime: Float, callback: Promise) = scope.launch {
+    fun skipToNext(initialTime: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.skipToNext()
@@ -407,9 +424,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
 
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun skipToPrevious(initialTime: Float, callback: Promise) = scope.launch {
+    fun skipToPrevious(initialTime: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.skipToPrevious()
@@ -420,9 +438,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
 
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun reset(callback: Promise) = scope.launch {
+    fun reset(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.stop()
@@ -431,188 +450,213 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
 
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun play(callback: Promise) = scope.launch {
+    fun play(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.play()
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun pause(callback: Promise) = scope.launch {
+    fun pause(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.pause()
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun stop(callback: Promise) = scope.launch {
+    fun stop(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.stop()
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun seekTo(seconds: Float, callback: Promise) = scope.launch {
+    fun seekTo(seconds: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.seekTo(seconds)
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun seekBy(offset: Float, callback: Promise) = scope.launch {
+    fun seekBy(offset: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.seekBy(offset)
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun retry(callback: Promise) = scope.launch {
+    fun retry(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.retry()
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun setVolume(volume: Float, callback: Promise) = scope.launch {
+    fun setVolume(volume: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.setVolume(volume)
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun getVolume(callback: Promise) = scope.launch {
+    fun getVolume(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.getVolume())
     }
+    }
 
     @ReactMethod
-    fun setRate(rate: Float, callback: Promise) = scope.launch {
+    fun setRate(rate: Float, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.setRate(rate)
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun getRate(callback: Promise) = scope.launch {
+    fun getRate(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.getRate())
     }
+    }
 
     @ReactMethod
-    fun setRepeatMode(mode: Int, callback: Promise) = scope.launch {
+    fun setRepeatMode(mode: Int, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.setRepeatMode(RepeatMode.fromOrdinal(mode))
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun getRepeatMode(callback: Promise) = scope.launch {
+    fun getRepeatMode(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.getRepeatMode().ordinal)
     }
+    }
 
     @ReactMethod
-    fun setPlayWhenReady(playWhenReady: Boolean, callback: Promise) = scope.launch {
+    fun setPlayWhenReady(playWhenReady: Boolean, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         musicService.playWhenReady = playWhenReady
         callback.resolve(null)
     }
+    }
 
     @ReactMethod
-    fun getPlayWhenReady(callback: Promise) = scope.launch {
+    fun getPlayWhenReady(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.playWhenReady)
     }
+    }
 
     @ReactMethod
-    fun getTrack(index: Int, callback: Promise) = scope.launch {
+    fun getTrack(index: Int, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         if (index >= 0 && index < musicService.tracks.size) {
-            callback.resolve(Arguments.fromBundle(musicService.tracks[index].originalItem))
+            callback.resolve(musicService.tracks[index].originalItem?.let { Arguments.fromBundle(it) })
         } else {
             callback.resolve(null)
         }
     }
+    }
 
     @ReactMethod
-    fun getQueue(callback: Promise) = scope.launch {
+    fun getQueue(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
-        callback.resolve(Arguments.fromList(musicService.tracks.map { it.originalItem }))
+        // Clone on main (the service mutates originalItem there), marshal off-main.
+        val bundles = musicService.tracks.map { track -> track.originalItem?.let(::Bundle) }
+        callback.resolve(withContext(Dispatchers.Default) { Arguments.fromList(bundles) })
+    }
     }
 
     @ReactMethod
-    fun setQueue(data: ReadableArray?, callback: Promise) = scope.launch {
+    fun setQueue(data: ReadableArray?, callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         try {
+            val tracks = withContext(Dispatchers.Default) { readableArrayToTrackList(data) }
             musicService.clear()
-            musicService.add(readableArrayToTrackList(data))
+            musicService.add(tracks)
             callback.resolve(null)
         } catch (exception: Exception) {
             rejectWithException(callback, exception)
         }
     }
+    }
 
     @ReactMethod
-    fun getActiveTrackIndex(callback: Promise) = scope.launch {
+    fun getActiveTrackIndex(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         callback.resolve(
             if (musicService.tracks.isEmpty()) null else musicService.getCurrentTrackIndex()
         )
     }
+    }
 
     @ReactMethod
-    fun getActiveTrack(callback: Promise) = scope.launch {
+    fun getActiveTrack(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         callback.resolve(
             if (musicService.tracks.isEmpty()) null
-            else Arguments.fromBundle(
-                musicService.tracks[musicService.getCurrentTrackIndex()].originalItem
-            )
+            else musicService.tracks[musicService.getCurrentTrackIndex()].originalItem
+                ?.let { Arguments.fromBundle(it) }
         )
     }
+    }
 
     @ReactMethod
-    fun getDuration(callback: Promise) = scope.launch {
+    fun getDuration(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.getDurationInSeconds())
     }
+    }
 
     @ReactMethod
-    fun getBufferedPosition(callback: Promise) = scope.launch {
+    fun getBufferedPosition(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.getBufferedPositionInSeconds())
     }
+    }
 
     @ReactMethod
-    fun getPosition(callback: Promise) = scope.launch {
+    fun getPosition(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
 
         callback.resolve(musicService.getPositionInSeconds())
     }
+    }
 
     @ReactMethod
-    fun getProgress(callback: Promise) = scope.launch {
+    fun getProgress(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         var bundle = Bundle()
         bundle.putDouble("duration", musicService.getDurationInSeconds());
@@ -620,10 +664,12 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
         bundle.putDouble("buffered", musicService.getBufferedPositionInSeconds());
         callback.resolve(Arguments.fromBundle(bundle))
     }
+    }
 
     @ReactMethod
-    fun getPlaybackState(callback: Promise) = scope.launch {
+    fun getPlaybackState(callback: Promise) { scope.launch {
         if (verifyServiceBoundOrReject(callback)) return@launch
         callback.resolve(Arguments.fromBundle(musicService.getPlayerStateBundle(musicService.state)))
     }
+    }
 }
diff --git a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
index afa6b0f..c6f01d5 100644
--- a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
+++ b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
@@ -741,7 +741,7 @@ class MusicService : HeadlessJsTaskService() {
 
     @MainThread
     private fun emit(event: String, data: Bundle? = null) {
-        reactNativeHost.reactInstanceManager.currentReactContext
+        (applicationContext as? com.facebook.react.ReactApplication)?.reactHost?.currentReactContext
             ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
             ?.emit(event, data?.let { Arguments.fromBundle(it) })
     }
@@ -751,7 +751,7 @@ class MusicService : HeadlessJsTaskService() {
         val payload = Arguments.createArray()
         data.forEach { payload.pushMap(Arguments.fromBundle(it)) }
 
-        reactNativeHost.reactInstanceManager.currentReactContext
+        (applicationContext as? com.facebook.react.ReactApplication)?.reactHost?.currentReactContext
             ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
             ?.emit(event, payload)
     }
