如何在React Native中监听Android端Java类的变量变化
监听Android端变量变化并关联React useEffect的正确方式
一、先解决hasActiveCatalystInstance()始终为false的问题
你在Module构造函数里调用sendHasValidServer()的时机太早——此时React实例还未完成初始化,所以hasActiveCatalystInstance()必然返回false。正确的做法是等到React宿主环境就绪后再发送事件,可以通过实现LifecycleEventListener监听React生命周期:
修改Native Module代码
import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.DeviceEventManagerModule; public class MyModule extends ReactContextBaseJavaModule implements LifecycleEventListener { private static final String TAG = "MyModule"; MyServer _server; private boolean hasValidServer = false; MyModule(ReactApplicationContext context) { super(context); // 注册生命周期监听 context.addLifecycleEventListener(this); try { _server = new Server(); hasValidServer = true; } catch(Exception e) { hasValidServer = false; } } @Override public String getName() { // 必须返回Module的唯一标识,JS端会用到 return "MyModule"; } // 实现生命周期监听方法 @Override public void onHostResume() { // React宿主就绪后发送初始状态 sendHasValidServer(hasValidServer); } @Override public void onHostPause() {} @Override public void onHostDestroy() { getReactApplicationContext().removeLifecycleEventListener(this); } @ReactMethod public void addListener(String eventName) { Log.e(TAG, "ADDING LISTENER"); } @ReactMethod public void removeListeners(Integer count) { Log.e(TAG, "REMOVING LISTENER"); } // Android端变量变化时调用此方法推送事件 public void updateServerStatus(boolean valid) { hasValidServer = valid; sendHasValidServer(valid); } private void sendHasValidServer(boolean valid) { ReactApplicationContext reactContext = getReactApplicationContext(); if (reactContext == null || !reactContext.hasActiveCatalystInstance()) { Log.e(TAG, "No active catalyst instance, skip sending event"); return; } WritableMap params = Arguments.createMap(); params.putBoolean("hasValidServer", valid); reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("onHasValidServer", params); } }
二、React端监听事件并关联useEffect
使用NativeEventEmitter接收Native推送的事件,通过状态变量关联useEffect,实现类似监听React变量的效果:
import { useEffect, useState } from 'react'; import { NativeEventEmitter, NativeModules } from 'react-native'; const { MyModule } = NativeModules; const myModuleEmitter = new NativeEventEmitter(MyModule); function App() { const [hasValidServer, setHasValidServer] = useState(false); useEffect(() => { // 订阅Native事件 const subscription = myModuleEmitter.addListener( 'onHasValidServer', (event) => setHasValidServer(event.hasValidServer) ); // 组件卸载时取消订阅 return () => subscription.remove(); }, []); // 监听hasValidServer变化,触发业务逻辑 useEffect(() => { console.log('服务器状态更新:', hasValidServer); // 这里写你需要执行的逻辑 }, [hasValidServer]); return ( // 你的组件UI ); } export default App;
三、解决“访问MyClass.x始终是初始值”的问题
直接通过MyClass.x访问Java变量只能拿到初始值,因为JS端不会自动同步Java变量变化,有两种解决方式:
- 事件推送:如上述代码,Java端变量变化时主动发送事件更新JS状态
- 主动拉取:在Native端添加方法供JS主动获取最新值:
JS端可调用@ReactMethod public void getServerStatus(Promise promise) { promise.resolve(hasValidServer); }MyModule.getServerStatus()获取最新状态。
四、额外注意事项
- 确保Native Module已正确注册到Package中,否则JS端无法获取
MyModule - 如果在后台线程更新Android变量,需切换到React主线程发送事件:
reactContext.runOnUiThread(() -> sendHasValidServer(valid));
内容的提问来源于stack exchange,提问作者Elliptica
相关产品推荐
相关产品推荐

