Android原生Activity向React Native传递Intent数据问题求助
嘿,别担心,刚接触Android+React Native遇到这种问题太正常啦~你碰到的核心问题是ReactContext在Activity的onCreate阶段还没完成初始化,直接调用getCurrentReactContext()肯定会拿到null,自然就触发空指针异常了。下面给你一步步解决的方案:
核心思路:等ReactContext初始化完成再发送事件
React Native的ReactInstanceManager是异步初始化RN环境的,onCreate的时候它还没准备好,所以我们得监听它的初始化完成事件,等上下文就绪后再把Intent的数据传给RN。
步骤1:修改你的CustomActivity代码
我们添加一个ReactContext的监听器,等它初始化完成后再发送Intent数据,同时处理应用已经在后台运行(ReactContext已经存在)的情况:
public class CustomActivity extends ReactActivity { private Intent incomingIntent; private ReactInstanceManager.ReactInstanceEventListener reactInstanceListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 先把外部传来的Intent保存起来 incomingIntent = getIntent(); // 创建监听器,监听ReactContext初始化完成事件 reactInstanceListener = new ReactInstanceManager.ReactInstanceEventListener() { @Override public void onReactContextInitialized(ReactContext context) { // 这里Context已经就绪,安全发送事件 sendIntentDataToRN(context); // 记得移除监听器,避免内存泄漏 getReactInstanceManager().removeReactInstanceEventListener(this); } }; // 给ReactInstanceManager添加监听器 getReactInstanceManager().addReactInstanceEventListener(reactInstanceListener); // 特殊情况:如果应用已经在后台运行,ReactContext可能已经初始化好了 if (getReactInstanceManager().hasStartedCreatingInitialContext()) { ReactContext currentContext = getReactInstanceManager().getCurrentReactContext(); if (currentContext != null) { sendIntentDataToRN(currentContext); getReactInstanceManager().removeReactInstanceEventListener(reactInstanceListener); } } } // 封装发送事件的方法 private void sendIntentDataToRN(ReactContext context) { WritableMap dataMap = Arguments.createMap(); // 从Intent里提取你需要的文本,这里以接收分享文本为例 String intentText = incomingIntent.getStringExtra(Intent.EXTRA_TEXT); // 如果没有拿到数据,给个默认值 dataMap.putString("messageString", intentText != null ? intentText : "暂无Intent数据"); try { context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("customEvent", dataMap); } catch (Exception e) { Log.e("ReactNative", "发送事件失败: " + e.getMessage()); } } @Override protected void onDestroy() { super.onDestroy(); // 页面销毁时一定要移除监听器,防止内存泄漏 if (reactInstanceListener != null && getReactInstanceManager() != null) { getReactInstanceManager().removeReactInstanceEventListener(reactInstanceListener); } } // 这里返回你的RN主组件名称,和默认ReactActivity一致 @Override protected String getMainComponentName() { return "YourAppName"; // 替换成你实际的App名称 } }
步骤2:RN端监听事件并展示数据
在你的RN主组件里,监听原生发来的事件,把数据展示在界面上:
import React, { Component } from 'react'; import { View, Text, DeviceEventEmitter } from 'react-native'; class MainScreen extends Component { state = { displayText: '等待Intent数据...' }; componentDidMount() { // 监听原生发送的customEvent事件 this.eventListener = DeviceEventEmitter.addListener('customEvent', (data) => { console.log('收到原生数据:', data.messageString); // 更新状态,展示数据 this.setState({ displayText: data.messageString }); }); } componentWillUnmount() { // 组件销毁时移除监听,避免内存泄漏 this.eventListener.remove(); } render() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text style={{ fontSize: 18 }}>{this.state.displayText}</Text> </View> ); } } export default MainScreen;
步骤3:配置AndroidManifest.xml
确保你的CustomActivity能接收外部Intent,比如添加接收文本分享的过滤器(根据你的需求调整):
<activity android:name=".CustomActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" <!-- 避免重复创建Activity,可选 --> android:windowSoftInputMode="adjustResize"> <!-- 接收外部文本分享的过滤器 --> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <!-- 主入口过滤器,保留应用桌面图标 --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
关键注意点
- 为什么
onCreate里拿不到ReactContext?因为RN的初始化是异步的,onCreate执行时RN环境还没搭建好,必须等onReactContextInitialized回调触发后才能安全使用上下文。 - 一定要在
onDestroy里移除监听器,否则会造成内存泄漏。 - 如果你的应用已经在后台运行,外部Intent启动Activity时,ReactContext可能已经存在,所以要做额外判断。
内容的提问来源于stack exchange,提问作者tepsijash
相关产品推荐
相关产品推荐

