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

Android非原生模块类向React Native发送事件的实现方法

问题

在React Native应用中,我有一个Android原生模块CameraModule.kt和CameraHomeFragment,需要从Fragment向React Native发送数据。

CameraModule.kt

class CameraModule(reactContext: ReactApplicationContext): ReactContextBaseJavaModule(reactContext) {

  override fun getName(): String = "CameraModule"

  private val context = reactApplicationContext

  @ReactMethod
  fun openCamera(){

    val intent = Intent(context,CameraActivity::class.java)
    if(intent.resolveActivity(context.packageManager) != null){
      intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
      context.startActivity(intent)
    }
  }

  fun emitEvent() {
    context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
      .emit("eventName", "params")
  }

}

CameraHomeFragment.kt

class CameraHomeFragment : Fragment() {

  private var viewBinding: FragmentCameraHomeBinding? = null

  override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
  ): View? {
    // Inflate the layout for this fragment

    viewBinding = FragmentCameraHomeBinding.inflate(inflater, container, false)
    return viewBinding?.root
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    viewBinding?.imageCaptureButton?.setOnClickListener {
      // emit an event here on clicking button
    }
  }
}

查阅官方文档后发现,文档未说明如何在没有React应用上下文的其他类中发送事件,该如何实现?


解决方案

要在Fragment中向React Native发送事件,核心是获取ReactApplicationContext,以下是几种可行实现方式:

方法一:通过自定义Application全局持有上下文

  1. 创建自定义Application类,全局维护React上下文:
class MyApp : Application(), ReactApplication {
    private val mReactNativeHost = object : ReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> {
            return PackageList(this).packages.apply {
                add(CameraModule(reactApplicationContext))
            }
        }

        override fun getJSMainModuleName(): String = "index"
    }

    override fun getReactNativeHost(): ReactNativeHost = mReactNativeHost

    // 对外提供获取React上下文的方法
    fun getReactContext(): ReactApplicationContext {
        return reactNativeHost.reactApplicationContext
    }
}
  1. 修改Fragment的点击事件,获取上下文并发送事件:
viewBinding?.imageCaptureButton?.setOnClickListener {
    val reactContext = (requireActivity().application as MyApp).getReactContext()
    reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
        .emit("imageCaptured", "拍摄的图片数据")
}

方法二:通过CameraModule单例持有上下文

  1. 修改CameraModule,用单例模式保存上下文:
class CameraModule(reactContext: ReactApplicationContext): ReactContextBaseJavaModule(reactContext) {
    companion object {
        private var INSTANCE: CameraModule? = null
        private var reactContext: ReactApplicationContext? = null

        fun getReactContext(): ReactApplicationContext? = reactContext
    }

    override fun getName(): String = "CameraModule"

    init {
        INSTANCE = this
        reactContext = reactApplicationContext
    }

    // 保留原有openCamera和emitEvent方法
}
  1. 在Fragment中直接调用获取上下文:
viewBinding?.imageCaptureButton?.setOnClickListener {
    CameraModule.getReactContext()?.let { context ->
        context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit("imageCaptured", "拍摄的图片数据")
    }
}

方法三:通过容器Activity传递上下文

如果CameraActivity是Fragment的容器,可在Activity中持有上下文,Fragment从Activity获取:

  1. 在CameraActivity中初始化并提供上下文:
class CameraActivity : AppCompatActivity() {
    private lateinit var reactContext: ReactApplicationContext

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        reactContext = (application as MyApp).getReactContext()
    }

    fun getReactContext(): ReactApplicationContext = reactContext
}
  1. 在Fragment中获取Activity的上下文:
viewBinding?.imageCaptureButton?.setOnClickListener {
    val reactContext = (requireActivity() as CameraActivity).getReactContext()
    reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
        .emit("imageCaptured", "拍摄的图片数据")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:05:29