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:
parent
d3a8b49f9b
commit
2f889f5855
@ -113,7 +113,7 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner {
|
|||||||
private var maxZoom: Float = 1f
|
private var maxZoom: Float = 1f
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
private var mHybridData: HybridData?
|
private var mHybridData: HybridData
|
||||||
|
|
||||||
@Suppress("LiftReturnOrAssignment", "RedundantIf")
|
@Suppress("LiftReturnOrAssignment", "RedundantIf")
|
||||||
internal val fallbackToSnapshot: Boolean
|
internal val fallbackToSnapshot: Boolean
|
||||||
@ -185,7 +185,7 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun finalize() {
|
fun finalize() {
|
||||||
mHybridData?.resetNative()
|
mHybridData.resetNative()
|
||||||
}
|
}
|
||||||
|
|
||||||
private external fun initHybrid(): HybridData
|
private external fun initHybrid(): HybridData
|
||||||
@ -478,7 +478,6 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner {
|
|||||||
const val TAG_PERF = "CameraView.performance"
|
const val TAG_PERF = "CameraView.performance"
|
||||||
|
|
||||||
private val propsThatRequireSessionReconfiguration = arrayListOf("cameraId", "format", "fps", "hdr", "lowLightBoost", "photo", "video", "frameProcessorFps")
|
private val propsThatRequireSessionReconfiguration = arrayListOf("cameraId", "format", "fps", "hdr", "lowLightBoost", "photo", "video", "frameProcessorFps")
|
||||||
|
|
||||||
private val arrayListOfZoom = arrayListOf("zoom")
|
private val arrayListOfZoom = arrayListOf("zoom")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,16 +155,16 @@ class CameraViewManager : SimpleViewManager<CameraView>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDropViewInstance(view: CameraView) {
|
override fun onDropViewInstance(view: CameraView) {
|
||||||
Log.d(REACT_CLASS, "onDropViewInstance() called!")
|
Log.d(TAG, "onDropViewInstance() called!")
|
||||||
super.onDropViewInstance(view)
|
super.onDropViewInstance(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String {
|
override fun getName(): String {
|
||||||
return REACT_CLASS
|
return TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val REACT_CLASS = "CameraView"
|
const val TAG = "CameraView"
|
||||||
|
|
||||||
val cameraViewTransactions: HashMap<CameraView, ArrayList<String>> = HashMap()
|
val cameraViewTransactions: HashMap<CameraView, ArrayList<String>> = HashMap()
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import kotlinx.coroutines.guava.await
|
|||||||
|
|
||||||
class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||||
companion object {
|
companion object {
|
||||||
const val REACT_CLASS = "CameraView"
|
const val TAG = "CameraView"
|
||||||
var RequestCode = 10
|
var RequestCode = 10
|
||||||
val FrameProcessorThread: ExecutorService = Executors.newSingleThreadExecutor()
|
val FrameProcessorThread: ExecutorService = Executors.newSingleThreadExecutor()
|
||||||
|
|
||||||
@ -42,10 +42,12 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
|
|||||||
|
|
||||||
override fun initialize() {
|
override fun initialize() {
|
||||||
super.initialize()
|
super.initialize()
|
||||||
FrameProcessorThread.execute {
|
if (frameProcessorManager == null) {
|
||||||
frameProcessorManager = FrameProcessorRuntimeManager(reactApplicationContext)
|
FrameProcessorThread.execute {
|
||||||
reactApplicationContext.runOnJSQueueThread {
|
frameProcessorManager = FrameProcessorRuntimeManager(reactApplicationContext)
|
||||||
frameProcessorManager!!.installJSIBindings()
|
reactApplicationContext.runOnJSQueueThread {
|
||||||
|
frameProcessorManager!!.installJSIBindings()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,10 +55,11 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
|
|||||||
override fun onCatalystInstanceDestroy() {
|
override fun onCatalystInstanceDestroy() {
|
||||||
super.onCatalystInstanceDestroy()
|
super.onCatalystInstanceDestroy()
|
||||||
frameProcessorManager?.destroy()
|
frameProcessorManager?.destroy()
|
||||||
|
frameProcessorManager = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String {
|
override fun getName(): String {
|
||||||
return REACT_CLASS
|
return TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findCameraView(id: Int): CameraView = reactApplicationContext.currentActivity?.findViewById(id) ?: throw ViewNotFoundError(id)
|
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 {
|
val secondsPerFrame = try {
|
||||||
cameraConfig.getOutputMinFrameDuration(formatId, size) / 1_000_000_000.0
|
cameraConfig.getOutputMinFrameDuration(formatId, size) / 1_000_000_000.0
|
||||||
} catch (error: Throwable) {
|
} 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
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +267,7 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
val difference = System.currentTimeMillis() - startTime
|
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
|
return@withPromise cameraDevices
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,7 @@ import java.lang.ref.WeakReference
|
|||||||
class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
|
class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "FrameProcessorRuntime"
|
const val TAG = "FrameProcessorRuntime"
|
||||||
private var HasRegisteredPlugins = false
|
|
||||||
val Plugins: ArrayList<FrameProcessorPlugin> = ArrayList()
|
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 {
|
init {
|
||||||
System.loadLibrary("reanimated")
|
System.loadLibrary("reanimated")
|
||||||
@ -32,15 +24,15 @@ class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
private var mHybridData: HybridData?
|
private var mHybridData: HybridData
|
||||||
private var mContext: WeakReference<ReactApplicationContext>?
|
private var mContext: WeakReference<ReactApplicationContext>
|
||||||
private var mScheduler: Scheduler?
|
private var mScheduler: Scheduler
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val holder = context.catalystInstance.jsCallInvokerHolder as CallInvokerHolderImpl
|
val holder = context.catalystInstance.jsCallInvokerHolder as CallInvokerHolderImpl
|
||||||
mScheduler = Scheduler(context)
|
mScheduler = Scheduler(context)
|
||||||
mContext = WeakReference(context)
|
mContext = WeakReference(context)
|
||||||
mHybridData = initHybrid(context.javaScriptContextHolder.get(), holder, mScheduler!!)
|
mHybridData = initHybrid(context.javaScriptContextHolder.get(), holder, mScheduler)
|
||||||
initializeRuntime()
|
initializeRuntime()
|
||||||
|
|
||||||
Log.i(TAG, "Installing Frame Processor Plugins...")
|
Log.i(TAG, "Installing Frame Processor Plugins...")
|
||||||
@ -48,19 +40,18 @@ class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
|
|||||||
registerPlugin(plugin)
|
registerPlugin(plugin)
|
||||||
}
|
}
|
||||||
Log.i(TAG, "Successfully installed ${Plugins.count()} Frame Processor Plugins!")
|
Log.i(TAG, "Successfully installed ${Plugins.count()} Frame Processor Plugins!")
|
||||||
HasRegisteredPlugins = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
mScheduler?.deactivate()
|
mScheduler.deactivate()
|
||||||
mHybridData?.resetNative()
|
mHybridData.resetNative()
|
||||||
}
|
}
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
@Keep
|
@Keep
|
||||||
fun findCameraViewById(viewId: Int): CameraView {
|
fun findCameraViewById(viewId: Int): CameraView {
|
||||||
Log.d(TAG, "finding view $viewId...")
|
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}")
|
Log.d(TAG, "found view $viewId! is null: ${view == null}")
|
||||||
return view ?: throw ViewNotFoundError(viewId)
|
return view ?: throw ViewNotFoundError(viewId)
|
||||||
}
|
}
|
||||||
@ -70,7 +61,7 @@ class FrameProcessorRuntimeManager(context: ReactApplicationContext) {
|
|||||||
jsContext: Long,
|
jsContext: Long,
|
||||||
jsCallInvokerHolder: CallInvokerHolderImpl,
|
jsCallInvokerHolder: CallInvokerHolderImpl,
|
||||||
scheduler: Scheduler
|
scheduler: Scheduler
|
||||||
): HybridData?
|
): HybridData
|
||||||
private external fun initializeRuntime()
|
private external fun initializeRuntime()
|
||||||
private external fun registerPlugin(plugin: FrameProcessorPlugin)
|
private external fun registerPlugin(plugin: FrameProcessorPlugin)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user