fix: Fix hot-reload crash caused by Frame Processor Runtime being initialized twice (#258)

* Fix Frame Processor Runtime being initialized twice causing a hot-reload to crash

* Remove unnecessary `HasRegisteredPlugins` singleton

* make non-optional

* `REACT_CLASS` -> `TAG`

* fix nullable
This commit is contained in:
Marc Rousavy 2021-07-07 15:00:32 +02:00 committed by GitHub
parent d3a8b49f9b
commit 2f889f5855
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 31 deletions

View File

@ -113,7 +113,7 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner {
private var maxZoom: Float = 1f
@DoNotStrip
private var mHybridData: HybridData?
private var mHybridData: HybridData
@Suppress("LiftReturnOrAssignment", "RedundantIf")
internal val fallbackToSnapshot: Boolean
@ -185,7 +185,7 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner {
}
fun finalize() {
mHybridData?.resetNative()
mHybridData.resetNative()
}
private external fun initHybrid(): HybridData
@ -478,7 +478,6 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner {
const val TAG_PERF = "CameraView.performance"
private val propsThatRequireSessionReconfiguration = arrayListOf("cameraId", "format", "fps", "hdr", "lowLightBoost", "photo", "video", "frameProcessorFps")
private val arrayListOfZoom = arrayListOf("zoom")
}
}

View File

@ -155,16 +155,16 @@ class CameraViewManager : SimpleViewManager<CameraView>() {
}
override fun onDropViewInstance(view: CameraView) {
Log.d(REACT_CLASS, "onDropViewInstance() called!")
Log.d(TAG, "onDropViewInstance() called!")
super.onDropViewInstance(view)
}
override fun getName(): String {
return REACT_CLASS
return TAG
}
companion object {
const val REACT_CLASS = "CameraView"
const val TAG = "CameraView"
val cameraViewTransactions: HashMap<CameraView, ArrayList<String>> = HashMap()
}

View File

@ -25,7 +25,7 @@ import kotlinx.coroutines.guava.await
class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
companion object {
const val REACT_CLASS = "CameraView"
const val TAG = "CameraView"
var RequestCode = 10
val FrameProcessorThread: ExecutorService = Executors.newSingleThreadExecutor()
@ -42,10 +42,12 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
override fun initialize() {
super.initialize()
FrameProcessorThread.execute {
frameProcessorManager = FrameProcessorRuntimeManager(reactApplicationContext)
reactApplicationContext.runOnJSQueueThread {
frameProcessorManager!!.installJSIBindings()
if (frameProcessorManager == null) {
FrameProcessorThread.execute {
frameProcessorManager = FrameProcessorRuntimeManager(reactApplicationContext)
reactApplicationContext.runOnJSQueueThread {
frameProcessorManager!!.installJSIBindings()
}
}
}
}
@ -53,10 +55,11 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
override fun onCatalystInstanceDestroy() {
super.onCatalystInstanceDestroy()
frameProcessorManager?.destroy()
frameProcessorManager = null
}
override fun getName(): String {
return REACT_CLASS
return TAG
}
private fun findCameraView(id: Int): CameraView = reactApplicationContext.currentActivity?.findViewById(id) ?: throw ViewNotFoundError(id)
@ -208,7 +211,7 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
val secondsPerFrame = try {
cameraConfig.getOutputMinFrameDuration(formatId, size) / 1_000_000_000.0
} catch (error: Throwable) {
Log.e(REACT_CLASS, "Minimum Frame Duration for MediaRecorder Output cannot be calculated, format \"$formatName\" is not supported.")
Log.e(TAG, "Minimum Frame Duration for MediaRecorder Output cannot be calculated, format \"$formatName\" is not supported.")
null
}
@ -264,7 +267,7 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
}
val difference = System.currentTimeMillis() - startTime
Log.w(REACT_CLASS, "CameraViewModule::getAvailableCameraDevices took: $difference ms")
Log.w(TAG, "CameraViewModule::getAvailableCameraDevices took: $difference ms")
return@withPromise cameraDevices
}
}

View File

@ -15,15 +15,7 @@ import java.lang.ref.WeakReference
class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
companion object {
const val TAG = "FrameProcessorRuntime"
private var HasRegisteredPlugins = false
val Plugins: ArrayList<FrameProcessorPlugin> = ArrayList()
get() {
if (HasRegisteredPlugins) {
throw Error("Tried to access Frame Processor Plugin list, " +
"but plugins have already been registered (list is frozen now!).")
}
return field
}
init {
System.loadLibrary("reanimated")
@ -32,15 +24,15 @@ class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
}
@DoNotStrip
private var mHybridData: HybridData?
private var mContext: WeakReference<ReactApplicationContext>?
private var mScheduler: Scheduler?
private var mHybridData: HybridData
private var mContext: WeakReference<ReactApplicationContext>
private var mScheduler: Scheduler
init {
val holder = context.catalystInstance.jsCallInvokerHolder as CallInvokerHolderImpl
mScheduler = Scheduler(context)
mContext = WeakReference(context)
mHybridData = initHybrid(context.javaScriptContextHolder.get(), holder, mScheduler!!)
mHybridData = initHybrid(context.javaScriptContextHolder.get(), holder, mScheduler)
initializeRuntime()
Log.i(TAG, "Installing Frame Processor Plugins...")
@ -48,19 +40,18 @@ class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
registerPlugin(plugin)
}
Log.i(TAG, "Successfully installed ${Plugins.count()} Frame Processor Plugins!")
HasRegisteredPlugins = true
}
fun destroy() {
mScheduler?.deactivate()
mHybridData?.resetNative()
mScheduler.deactivate()
mHybridData.resetNative()
}
@DoNotStrip
@Keep
fun findCameraViewById(viewId: Int): CameraView {
Log.d(TAG, "finding view $viewId...")
val view = mContext?.get()?.currentActivity?.findViewById<CameraView>(viewId)
val view = mContext.get()?.currentActivity?.findViewById<CameraView>(viewId)
Log.d(TAG, "found view $viewId! is null: ${view == null}")
return view ?: throw ViewNotFoundError(viewId)
}
@ -70,7 +61,7 @@ class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
jsContext: Long,
jsCallInvokerHolder: CallInvokerHolderImpl,
scheduler: Scheduler
): HybridData?
): HybridData
private external fun initializeRuntime()
private external fun registerPlugin(plugin: FrameProcessorPlugin)