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

React Native Android原生模块:如何观察并发送LiveData?

React Native原生模块监听LiveData解决方案

针对你遇到的NativeModule无LifecycleOwner、observeForever线程限制的问题,可以通过自定义LifecycleOwner来解决,以下是具体实现方案:

1. 实现自定义LifecycleOwner

创建内部类实现LifecycleOwner,用LifecycleRegistry管理生命周期状态,确保所有生命周期操作都在主线程执行:

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.facebook.react.bridge.UiThreadUtil

private class CustomLifecycleOwner : LifecycleOwner {
    private val lifecycleRegistry = LifecycleRegistry(this)

    init {
        // 初始化状态为RESUMED,确保LiveData能正常发送事件
        UiThreadUtil.runOnUiThread {
            lifecycleRegistry.currentState = Lifecycle.State.RESUMED
        }
    }

    override fun getLifecycle(): Lifecycle = lifecycleRegistry

    fun destroy() {
        UiThreadUtil.runOnUiThread {
            lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
        }
    }
}

2. 修改MyModule实现监听与移除逻辑

在模块中初始化自定义LifecycleOwner,管理LiveData的观察者,同时处理线程问题:

package com.my.module

import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.Arguments
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.facebook.react.bridge.UiThreadUtil
import androidx.lifecycle.Observer
import com.someone.extsdk

class MyModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
  
  override fun getName() = "MyModule"  

  // 自定义LifecycleOwner实例
  private val lifecycleOwner = CustomLifecycleOwner()
  // 存储LiveData的观察者,用于后续移除
  private var dataObserver: Observer<YourDataType>? = null

  @ReactMethod fun connect(id: String, promise: Promise) {
    extsdk.connect(
      onSuccess = { promise.resolve(null) },
      onError =  { e -> promise.reject("connect", e.toString())}
    )
  }  

  @ReactMethod fun disconnect() {
    extsdk.disconnect()
  }  


  @ReactMethod fun addListener(eventName: String) {
    // 确保在主线程操作LiveData的observe
    UiThreadUtil.runOnUiThread {
      dataObserver = Observer { data ->
        // 将数据转换为RN可接收的WritableMap
        val params = Arguments.createMap()
        // 根据你的数据类型填充params,示例:
        // params.putString("dataId", data.id)
        // params.putInt("dataValue", data.value)
        sendEvent(reactContext, eventName, params)
      }
      // 使用自定义LifecycleOwner监听LiveData
      extsdk.liveData.observe(lifecycleOwner, dataObserver!!)
    }
  }
  
  @ReactMethod fun removeListeners(count: Int) {
    UiThreadUtil.runOnUiThread {
      dataObserver?.let {
        extsdk.liveData.removeObserver(it)
        dataObserver = null
      }
    }
  }

  private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap?) {
    reactContext
      .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
      .emit(eventName, params)
  }

  override fun onCatalystInstanceDestroy() {
    super.onCatalystInstanceDestroy()
    // 模块销毁时清理资源,避免内存泄漏
    removeListeners(1)
    lifecycleOwner.destroy()
  }

  // 自定义LifecycleOwner内部类
  private class CustomLifecycleOwner : LifecycleOwner {
      private val lifecycleRegistry = LifecycleRegistry(this)

      init {
          UiThreadUtil.runOnUiThread {
              lifecycleRegistry.currentState = Lifecycle.State.RESUMED
          }
      }

      override fun getLifecycle(): Lifecycle = lifecycleRegistry

      fun destroy() {
          UiThreadUtil.runOnUiThread {
              lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
          }
      }
  }
}

关键说明

  • 自定义LifecycleOwner:通过LifecycleRegistry手动管理生命周期状态,初始化设置为RESUMED确保LiveData观察者能持续接收事件;模块销毁时切换到DESTROYED状态清理资源。
  • 线程安全:所有涉及Lifecycle和LiveData的操作都通过UiThreadUtil.runOnUiThread确保在主线程执行,规避线程报错。
  • 观察者管理:将Observer实例存储在模块中,方便在removeListeners时准确移除,避免内存泄漏。
  • 模块销毁清理:重写onCatalystInstanceDestroy方法,在模块销毁时主动移除观察者并销毁LifecycleOwner,确保资源完全释放。

替换代码中的YourDataType为extsdk.liveData实际的数据类型,并根据数据结构调整params的填充逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:18:10