From d5d9df273aec5abda4100bc6e155eb48779001c6 Mon Sep 17 00:00:00 2001 From: hannomargelo Date: Wed, 24 Sep 2025 15:21:46 +0200 Subject: [PATCH 1/2] reproduction for crash --- .../java/com/fabricexample/MainApplication.kt | 1 + .../java/com/fabricexample/MyCustomView.kt | 62 +++++++++++++++++ apps/src/tests/TestRecyclingViews.tsx | 68 +++++++++++++++++++ apps/src/tests/index.ts | 1 + 4 files changed, 132 insertions(+) create mode 100644 FabricExample/android/app/src/main/java/com/fabricexample/MyCustomView.kt create mode 100644 apps/src/tests/TestRecyclingViews.tsx diff --git a/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt b/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt index 154a66709b..b95cb0c50d 100644 --- a/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt +++ b/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt @@ -21,6 +21,7 @@ class MainApplication : Application(), ReactApplication { PackageList(this).packages.apply { // Packages that cannot be autolinked yet can be added manually here, for example: // add(MyReactNativePackage()) + add(CustomViewPackage()) } override fun getJSMainModuleName(): String = "index" diff --git a/FabricExample/android/app/src/main/java/com/fabricexample/MyCustomView.kt b/FabricExample/android/app/src/main/java/com/fabricexample/MyCustomView.kt new file mode 100644 index 0000000000..4faae79775 --- /dev/null +++ b/FabricExample/android/app/src/main/java/com/fabricexample/MyCustomView.kt @@ -0,0 +1,62 @@ +package com.fabricexample + +import android.annotation.SuppressLint +import android.util.Log +import android.view.View +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.uimanager.SimpleViewManager +import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.ViewManager + +@SuppressLint("ViewConstructor") +class MyCustomView(context: ThemedReactContext) : View(context) { + override fun onAttachedToWindow() { + super.onAttachedToWindow() + Log.d("HannoDebug", "MyCustomView: onAttachedToWindow called for view: $this, id: ${this.id}, to: ${this.parent}") + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + Log.d("HannoDebug", "MyCustomView: onDetachedFromWindow called for view: $this, id: ${this.id}, from: ${this.parent}") + // print callstack: + Exception().printStackTrace() + } +} + +@ReactModule(name = "CustomView") +class CustomViewManager : SimpleViewManager() { + override fun getName() = "CustomView" + + companion object { + @SuppressLint("StaticFieldLeak") + var viewInstance: MyCustomView? = null + } + +// init { +// mRecyclableViews = HashMap() +// } + + override fun createViewInstance(reactContext: ThemedReactContext): MyCustomView { + Log.d("HannoDebug", "CustomViewManager: createViewInstance called") + if (viewInstance == null) { + viewInstance = MyCustomView(reactContext) + viewInstance!!.setBackgroundColor(0xFFFF0000.toInt()) // Red background for visibility + } + return viewInstance!! + } + + override fun onDropViewInstance(view: MyCustomView) { + super.onDropViewInstance(view) + prepareToRecycleView(view.context as ThemedReactContext, view) + Log.d("HannoDebug", "CustomViewManager: onDropViewInstance called") + } +} + +class CustomViewPackage : ReactPackage { + override fun createViewManagers(reactContext: ReactApplicationContext): List> { + return listOf(CustomViewManager()) + } + +} \ No newline at end of file diff --git a/apps/src/tests/TestRecyclingViews.tsx b/apps/src/tests/TestRecyclingViews.tsx new file mode 100644 index 0000000000..c12fcf799b --- /dev/null +++ b/apps/src/tests/TestRecyclingViews.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import {Button, requireNativeComponent, View} from 'react-native'; +import {NavigationContainer, useNavigation} from '@react-navigation/native'; +import {createNativeStackNavigator} from '@react-navigation/native-stack'; + +const Stack = createNativeStackNavigator(); + +const CustomView = requireNativeComponent('CustomView'); + +function HomeScreen() { + const navigation = useNavigation(); + return ( + +