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全局持有上下文
- 创建自定义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 } }
- 修改Fragment的点击事件,获取上下文并发送事件:
viewBinding?.imageCaptureButton?.setOnClickListener { val reactContext = (requireActivity().application as MyApp).getReactContext() reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit("imageCaptured", "拍摄的图片数据") }
方法二:通过CameraModule单例持有上下文
- 修改
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方法 }
- 在Fragment中直接调用获取上下文:
viewBinding?.imageCaptureButton?.setOnClickListener { CameraModule.getReactContext()?.let { context -> context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit("imageCaptured", "拍摄的图片数据") } }
方法三:通过容器Activity传递上下文
如果CameraActivity是Fragment的容器,可在Activity中持有上下文,Fragment从Activity获取:
- 在
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 }
- 在Fragment中获取Activity的上下文:
viewBinding?.imageCaptureButton?.setOnClickListener { val reactContext = (requireActivity() as CameraActivity).getReactContext() reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit("imageCaptured", "拍摄的图片数据") }
内容的提问来源于stack exchange,提问作者chayan das
相关产品推荐
相关产品推荐

