From 0a044b2ddab0c19266a9c5a8a29c26001755cca6 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 2 Sep 2025 08:29:59 -0700 Subject: [PATCH] Decouple TimerExecutor creation from ReactInstance Summary: Simplify construction to save a JNI call, slightly more efficient on binary size too (1KiB hah) Changelog: [Internal] Differential Revision: D81445834 --- .../com/facebook/react/runtime/JSTimerExecutor.kt | 13 +++++++++---- .../com/facebook/react/runtime/ReactInstance.kt | 6 +----- .../main/jni/react/runtime/jni/JJSTimerExecutor.cpp | 6 ++++++ .../main/jni/react/runtime/jni/JJSTimerExecutor.h | 6 ++++-- .../main/jni/react/runtime/jni/JReactInstance.cpp | 8 -------- .../src/main/jni/react/runtime/jni/JReactInstance.h | 6 ------ 6 files changed, 20 insertions(+), 25 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/JSTimerExecutor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/JSTimerExecutor.kt index 87b1a027355a58..15c11a07531a18 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/JSTimerExecutor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/JSTimerExecutor.kt @@ -7,15 +7,20 @@ package com.facebook.react.runtime -import com.facebook.jni.HybridData -import com.facebook.jni.annotations.DoNotStripAny +import com.facebook.jni.HybridClassBase +import com.facebook.jni.annotations.DoNotStrip import com.facebook.react.bridge.WritableArray import com.facebook.react.bridge.WritableNativeArray import com.facebook.react.modules.core.JavaScriptTimerExecutor import com.facebook.soloader.SoLoader -@DoNotStripAny -internal class JSTimerExecutor(private val mHybridData: HybridData) : JavaScriptTimerExecutor { +@DoNotStrip +internal class JSTimerExecutor() : HybridClassBase(), JavaScriptTimerExecutor { + init { + initHybrid() + } + + private external fun initHybrid() private external fun callTimers(timerIDs: WritableNativeArray) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt index 96bb76b3b2a092..4999f867050426 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt @@ -76,7 +76,6 @@ import java.util.ArrayList import java.util.HashMap import java.util.HashSet import kotlin.collections.Collection -import kotlin.jvm.JvmStatic /** * A replacement for [com.facebook.react.bridge.CatalystInstance] responsible for creating and @@ -126,7 +125,7 @@ internal class ReactInstance( ReactChoreographer.initialize(AndroidChoreographerProvider.getInstance()) devSupportManager.startInspector() - val jsTimerExecutor = createJSTimerExecutor() + val jsTimerExecutor = JSTimerExecutor() javaTimerManager = JavaTimerManager( context, @@ -182,7 +181,6 @@ internal class ReactInstance( getJSCallInvokerHolder(), getNativeMethodCallInvokerHolder(), ) - Systrace.endSection(Systrace.TRACE_TAG_REACT) // Set up Fabric @@ -633,7 +631,5 @@ internal class ReactInstance( SystraceMessage.endSection(Systrace.TRACE_TAG_REACT).flush() } } - - @JvmStatic @DoNotStrip private external fun createJSTimerExecutor(): JSTimerExecutor } } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp index 0e2a390b9e4fae..f6aed2d17dba6c 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp @@ -12,6 +12,11 @@ namespace facebook::react { +void JJSTimerExecutor::initHybrid( + jni::alias_ref jobj) { + setCxxInstance(jobj); +} + void JJSTimerExecutor::setTimerManager( std::weak_ptr timerManager) { timerManager_ = timerManager; @@ -28,6 +33,7 @@ void JJSTimerExecutor::callTimers(WritableNativeArray* timerIDs) { void JJSTimerExecutor::registerNatives() { registerHybrid({ makeNativeMethod("callTimers", JJSTimerExecutor::callTimers), + makeNativeMethod("initHybrid", JJSTimerExecutor::initHybrid), }); } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.h b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.h index cc7d938506540d..a3b89ebb6f6492 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.h @@ -17,18 +17,20 @@ namespace facebook::react { class JJSTimerExecutor : public jni::HybridClass { public: - JJSTimerExecutor() = default; - constexpr static auto kJavaDescriptor = "Lcom/facebook/react/runtime/JSTimerExecutor;"; static void registerNatives(); + static void initHybrid(jni::alias_ref jobj); + void setTimerManager(std::weak_ptr timerManager); void callTimers(WritableNativeArray* timerIDs); private: + JJSTimerExecutor() = default; + friend HybridBase; std::weak_ptr timerManager_; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp index 5ffd7492ba8132..f0b5e62826a11d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp @@ -168,12 +168,6 @@ JReactInstance::getNativeMethodCallInvokerHolder() { return nativeMethodCallInvokerHolder_; } -jni::global_ref -JReactInstance::createJSTimerExecutor( - jni::alias_ref /* unused */) { - return jni::make_global(JJSTimerExecutor::newObjectCxxArgs()); -} - void JReactInstance::callFunctionOnModule( const std::string& moduleName, const std::string& methodName, @@ -217,8 +211,6 @@ void JReactInstance::unregisterFromInspector() { void JReactInstance::registerNatives() { registerHybrid({ makeNativeMethod("initHybrid", JReactInstance::initHybrid), - makeNativeMethod( - "createJSTimerExecutor", JReactInstance::createJSTimerExecutor), makeNativeMethod( "loadJSBundleFromAssets", JReactInstance::loadJSBundleFromAssets), makeNativeMethod( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h index d6552a8a97895f..2b42b70507eff3 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h @@ -50,12 +50,6 @@ class JReactInstance : public jni::HybridClass { jni::alias_ref jReactHostInspectorTarget); - /* - * Instantiates and returns an instance of `JSTimerExecutor`. - */ - static jni::global_ref createJSTimerExecutor( - jni::alias_ref /* unused */); - static void registerNatives(); void loadJSBundleFromAssets(