From 79b690e17260fce73a7b513bc0c10948842afdd0 Mon Sep 17 00:00:00 2001 From: davidliu Date: Sat, 8 Feb 2025 00:50:40 +0900 Subject: [PATCH] fix: fix crash on android when reloading the react-native app --- .../livekit/reactnative/LiveKitReactNative.kt | 31 +++++++++++++++---- .../reactnative/LivekitReactNativeModule.kt | 13 ++++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/livekit/reactnative/LiveKitReactNative.kt b/android/src/main/java/com/livekit/reactnative/LiveKitReactNative.kt index 2ccdd986..f2cbe7be 100644 --- a/android/src/main/java/com/livekit/reactnative/LiveKitReactNative.kt +++ b/android/src/main/java/com/livekit/reactnative/LiveKitReactNative.kt @@ -1,24 +1,27 @@ package com.livekit.reactnative +import android.annotation.SuppressLint import android.app.Application import android.content.Context import android.os.Build import com.livekit.reactnative.audio.AudioType -import com.livekit.reactnative.video.CustomVideoEncoderFactory import com.livekit.reactnative.video.CustomVideoDecoderFactory +import com.livekit.reactnative.video.CustomVideoEncoderFactory import com.oney.WebRTCModule.WebRTCModuleOptions import org.webrtc.audio.JavaAudioDeviceModule object LiveKitReactNative { - private lateinit var adm: JavaAudioDeviceModule + + private var audioType: AudioType = AudioType.CommunicationAudioType() + + @SuppressLint("StaticFieldLeak") + private var adm: JavaAudioDeviceModule? = null val audioDeviceModule: JavaAudioDeviceModule get() { - if(!::adm.isInitialized) { - throw IllegalStateException("Audio device module is not initialized! Did you remember to call LiveKitReactNative.setup in your Application.onCreate?") - } - + val adm = this.adm + ?: throw IllegalStateException("Audio device module is not initialized! Did you remember to call LiveKitReactNative.setup in your Application.onCreate?") return adm } @@ -34,11 +37,17 @@ object LiveKitReactNative { context: Context, audioType: AudioType = AudioType.CommunicationAudioType() ) { + this.audioType = audioType val options = WebRTCModuleOptions.getInstance() options.videoEncoderFactory = CustomVideoEncoderFactory(null, true, true) options.videoDecoderFactory = CustomVideoDecoderFactory() options.enableMediaProjectionService = true + setupAdm(context) + options.audioDeviceModule = adm + } + + private fun setupAdm(context: Context) { val useHardwareAudioProcessing = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q adm = JavaAudioDeviceModule.builder(context) @@ -46,7 +55,17 @@ object LiveKitReactNative { .setUseHardwareNoiseSuppressor(useHardwareAudioProcessing) .setAudioAttributes(audioType.audioAttributes) .createAudioDeviceModule() + } + + internal fun invalidate(context: Context) { + val options = WebRTCModuleOptions.getInstance() + if (options.audioDeviceModule == adm) { + options.audioDeviceModule = null + } + adm?.release() + adm = null + setupAdm(context) options.audioDeviceModule = adm } } \ No newline at end of file diff --git a/android/src/main/java/com/livekit/reactnative/LivekitReactNativeModule.kt b/android/src/main/java/com/livekit/reactnative/LivekitReactNativeModule.kt index 85709ee5..745f1cc6 100644 --- a/android/src/main/java/com/livekit/reactnative/LivekitReactNativeModule.kt +++ b/android/src/main/java/com/livekit/reactnative/LivekitReactNativeModule.kt @@ -1,9 +1,12 @@ package com.livekit.reactnative -import android.annotation.SuppressLint -import android.content.Context import android.media.AudioAttributes -import com.facebook.react.bridge.* +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactContextBaseJavaModule +import com.facebook.react.bridge.ReactMethod +import com.facebook.react.bridge.ReadableMap import com.livekit.reactnative.audio.AudioDeviceKind import com.livekit.reactnative.audio.AudioManagerUtils import com.livekit.reactnative.audio.AudioSwitchManager @@ -120,4 +123,8 @@ class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactCon audioManager.selectAudioOutput(AudioDeviceKind.fromTypeName(deviceId)) promise.resolve(null) } + + override fun invalidate() { + LiveKitReactNative.invalidate(reactApplicationContext) + } }