You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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主动获取最新值:
    @ReactMethod
    public void getServerStatus(Promise promise) {
        promise.resolve(hasValidServer);
    }
    
    JS端可调用MyModule.getServerStatus()获取最新状态。

四、额外注意事项

  • 确保Native Module已正确注册到Package中,否则JS端无法获取MyModule
  • 如果在后台线程更新Android变量,需切换到React主线程发送事件:
    reactContext.runOnUiThread(() -> sendHasValidServer(valid));
    

内容的提问来源于stack exchange,提问作者Elliptica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:40:27