Android与RN的交互与通信
文章目录
简介
这块算是RN入门的最后一块内容,跨端之间的交互问题。
两端交互是双向的,那么就会区分为
- RN通知Android调用方法
- Android通知RN调用方法
这边就着官网讲解一下两种情况的实现方式。
RN通知Android调用方法
这块页可以划分为两块
- RN使用Android原生的控件
- RN调用Android原生的方法
RN使用Android原生的控件
虽然RN本身提供了很多的组件可供使用,但是很多原生封装好的功能强大的控件,RN也可以直接使用
本文以ImageView为例,让RN使用原生ImageView并走Glide加载流程
声明控件管理类(原生)
class ReactImageManager: SimpleViewManager<ImageView>(){companionobject{constval MY_IMAGE_VIEW ="MyImageView"}overridefungetName(): String = MY_IMAGE_VIEW
overridefuncreateViewInstance(p0: ThemedReactContext): ImageView {returnImageView(p0)}@ReactProp(name ="src")funsetSrc(view: ImageView, url: String){
Log.d("React","加载图片。 url: $url")
Glide.with(view.context).load(url).placeholder(R.mipmap.ic_launcher).into(view)}}
最简单的控件管理类就这样给你撂在这了:
- SimpleViewManager里的泛型,代表了要给RN使用的原生控件是什么
- 重写方法getName,用于RN定位到使用的原生控件
- 重写方法createViewInstance,用于构建原生控件对象
- 声明RN属性,指定属性src,方法体里表明接收到src属性后会执行Glide加载流程
Package中进行注册
不管是方法还是控件,都需要在创建的Package中进行注册,那么对于刚创建的ReactImageManager,我们也需要将其注册到Package中。
class MyAppPackage: ReactPackage {overridefuncreateNativeModules(p0: ReactApplicationContext): MutableList<NativeModule>{returnmutableListOf(XXX)//注册 使用原生方法}overridefuncreateViewManagers(p0: ReactApplicationContext): MutableList<ViewManager<*,*>>{returnmutableListOf((ReactImageManager()))// 注册 使用原生控件}}
当然,这个package是需要添加到ReactInstanceManager的packages中的,这个就不多介绍了
RN中声明该控件
十分简单,通过requireComponent(第二步中getName的名称)即可
import {requireNativeComponent, View} from "react-native";
export const MyImageView = requireNativeComponent('MyImageView')
OK,这样我们就有了一个原生控件,并声明为MyImageView,可以在标签中使用
使用
既然MyImageView已经被声明好了,那么直接使用即可,且src为他的属性,直接看代码
<MyImageView
style={ { width: 200, height: 200, backgroundColor: 'blue' } }
src="https://www.qmbk.com/jingyan/UploadFiles_2374/20210621/2021062114402849.jpg"
/>
RN调用Android原生的方法
声明Module类(原生)
所有相关原生的方法都是放在这个module中的
classCalendarModule(privateval reactContext: ReactApplicationContext):ReactContextBaseJavaModule(reactContext){overridefungetName(): String ="CalendarModule"}
getName用于RN找到指定的Module,所有的原生方法将会定义在这个Module中
Package中注册
还记得上面说的注册吗,里面那个module,注册一下
class MyAppPackage: ReactPackage {overridefuncreateNativeModules(p0: ReactApplicationContext): MutableList<NativeModule>{returnmutableListOf(CalendarModule(p0))//注册 使用原生方法}overridefuncreateViewManagers(p0: ReactApplicationContext): MutableList<ViewManager<*,*>>{returnmutableListOf((ReactImageManager()))// 注册 使用原生控件}}
声明原生方法并使用
所有供RN使用的原生方法,都需要通过@ReactMethod标识
普通方法
@ReactMethodfuncreateCalendarEvent(name: String, location: String){}
这边声明了一个方法,有俩参数,来看下RN中的调用
NativeModules.CalendarModule.createCalendarEvent("testName", "testLocation")
OK非常的简单,NativeModules是要导包的,后面.CalendarModule代表你要使用的module,底层原理是一个map映射,这个要和前面getName的值一一对应,再后面就是.你的方法了,十分清晰。
回调方法
@ReactMethodfundoCallback(successCallback: Callback, errorCallback: Callback){try{val eventId =123
successCallback.invoke(eventId)}catch(e: Exception){
errorCallback.invoke(e)}}
参数这玩意想给几个都行,调用的时候一一对应即可,触发方法通过invoke。来看下RN中的调用
NativeModules.CalendarModule.doCallback(
(eventId) => {
console.log(eventId)
},
(e) => {
console.log(e)
}
)
我想这个不用过多介绍了应该,怎么声明怎么调用
Promise方法
另一种回调的实现方式,通过异步Promise来实现
@ReactMethodfuncreateCalendarEventPromise(name: String, location: String, promise: Promise){val eventId =123
Log.d("CalendarModule","Create event called with name: $name and location: $location")try{
promise.resolve(eventId)}catch(e: Throwable){
promise.reject("error",e)}}
调用方就比较特殊了,满足Promise的特性
NativeModules.CalendarModule.createCalendarEventPromise("testName", "testLocation").then(
(eventId) => {
console.log(eventId)
}
).catch(
(error) => console.log(error)
)
这就属于Promise的用法了,这边就不做介绍了。
Android通知RN调用方法
相比较之下,原生通知RN的方法就更为渐变了。
主要发送事件的方法为:
privatefunsendEvent(reactContext: ReactContext, eventName: String, params: WritableMap?){
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java).emit(eventName, params)}
简单描述一下参数:
reactContext上下文不多说了
eventName事件名称,RN需要通过这个名称去匹配
params参数的键值对,RN通过key来取值
举个例子:
val params = Arguments.createMap().apply{putString("myParams","hhh")}sendEvent(reactContext,"Event", params)
ok,这就发送了一个事件,事件名称为Event,传参为key:myParams, value:hhh
再来看下接收方的代码(RN):
在一个方法中为其添加监听:
DeviceEventEmitter.addListener('Event', event => {
console.log(event.myParams);
})
看到这段代码,就发现两端一一对应上了。
'Event’代表了事件的名称,
event为传来的map对象
event.myParams则取key为myParams的值
总结
Android和RN之间的双向交互到这里就给你交待清除了,基本上都是官网的实现方式,想要更好的使用就需要做一系列的封装了。不过呢,通过这篇文章,相信门就给你入了。
版权归原作者 我是你tangge 所有, 如有侵权,请联系我们删除。