0

I have following implementation (I've skipped imports and some parts):

class MainActivity : ReactActivity(), DefaultHardwareBackBtnHandler, PermissionAwareActivity {
    var communicationModule: CommunicationModule? = null
    

    fun sendMessageToNative(message: String) {
        val manager = (application as MyApplication).reactNativeHost.reactInstanceManager
        val reactContext = manager.currentReactContext

        if (reactContext != null) {
            val module = reactContext?.getNativeModule(CommunicationModule::class.java)
            if (module != null) {
                module.emitOnPush(message)
            } 
        } else {
            manager.addReactInstanceEventListener(object :
                ReactInstanceManager.ReactInstanceEventListener {
                    override fun onReactContextInitialized(context: ReactContext) {
                        val module = context.getNativeModule(CommunicationNewModule::class.java)
                        if (module != null) {
                            module.emitOnPush(message)
                        } 
                    }
            })
            manager.createReactContextInBackground()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(null)
        // ...
    }

    override fun onBackPressed() {
        super.onBackPressed()
        sendMessageToNative("MY_MESSAGE") // this doesn't work (no event on RN side)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        // assume this is not empty
        val myMessage = intent?.extras["message"]
        sendMessageToNative("MY_MESSAGE") // this doesn't work (no event on RN side)
    }
}

and Turbo Module (NativeCommunication.ts)

import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes';

export interface Spec extends TurboModule {
    onPush: EventEmitter<string>;
}

export default TurboModuleRegistry.getEnforcing<Spec>(
    'NativeCommunication',
);

and Kotlin's (CommunicationModule.kt)

@ReactModule(name = CommunicationModule.NAME)
class CommunicationModule(private val reactContext: ReactApplicationContext) : NativeCommunicationSpec(reactContext) {

    override fun getName() = NAME

    companion object {
        const val NAME = "NativeCommunication"
    }
}

and finally setting listeners on React Native side (e.g. in some page or MyPage.tsx)

const MyPage = ({ navigation }: MyPageProps): JSX.Element => {
    const listenerSubscription = useRef<null | EventSubscription>(null);
    const callbackMethod = (message: string) => { console.log(message) }

    useEffect(() => {
        listenerSubscription.current = NativeCommunication?.onPush(callbackMethod);
        return () => {
            listenerSubscription.current?.remove();
            listenerSubscription.current = null;
        }
    }, []);
}

PROBLEM: events trigered in onNewIntent and onBackPressed do not arrive to React Native.

My implementation works (events arrive to React Native) only when triggered from

fun MainActivity.newSessionTimer(): CountDownTimer {
    val sessionTimerFinishAfter = inMilliseconds(30, TimeUnit.Second)
    val sessionTimerTickEvery = inMilliseconds(30, TimeUnit.Second)
    return object : CountDownTimer(sessionTimerFinishAfter, sessionTimerTickEvery) {
        override fun onTick(millisUntilFinished: Long) { /** no-op */ }
        override fun onFinish() { sendMessageToNative("MY_MESSAGE") }
    }
}

GOAL: Be able to send messages from onNewIntent and onBackPressed and receive them on MyPage.tsx

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.