0


Android与RN的交互与通信

Android与RN的交互与通信

文章目录

简介

这块算是RN入门的最后一块内容,跨端之间的交互问题。
两端交互是双向的,那么就会区分为

  1. RN通知Android调用方法
  2. Android通知RN调用方法

这边就着官网讲解一下两种情况的实现方式。

RN通知Android调用方法

这块页可以划分为两块

  1. RN使用Android原生的控件
  2. 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)}}

最简单的控件管理类就这样给你撂在这了:

  1. SimpleViewManager里的泛型,代表了要给RN使用的原生控件是什么
  2. 重写方法getName,用于RN定位到使用的原生控件
  3. 重写方法createViewInstance,用于构建原生控件对象
  4. 声明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之间的双向交互到这里就给你交待清除了,基本上都是官网的实现方式,想要更好的使用就需要做一系列的封装了。不过呢,通过这篇文章,相信门就给你入了。

标签: android react native

本文转载自: https://blog.csdn.net/qq_42430654/article/details/138540993
版权归原作者 我是你tangge 所有, 如有侵权,请联系我们删除。

“Android与RN的交互与通信”的评论:

还没有评论