React Native 与 Android 通信
Christy4166
8年前
<p>本篇内容同样和React Native 与 原生App有关,可以说更加深入了两者之间的感情,为培养下一代做出准备:React Native与原生App的通信交互。</p> <p>Android系统为我们提供了webview来加载网页,同样为了让webview加载的网页可以与App交互,同样提供了一套机制帮助我们更方便的实现通信。为了实现React Native与原生App之间的通信,FB也实现了自己的一套交互机制。</p> <p>(1) RCTDeviceEventEmitter 事件方式</p> <p>(2) Callback 回调方式</p> <p>(3) Promise</p> <p>三种方式各具不同优缺点</p> <p>1.RCTDeviceEventEmitter</p> <p>优点:可任意时刻传递,Native主导控制。</p> <p>2.Callback</p> <p>优点:JS调用,Native返回。</p> <p>缺点:CallBack为异步操作,返回时机不确定</p> <p>3.Promise</p> <p>优点:JS调用,Native返回。</p> <p>缺点:每次使用需要JS调用一次</p> <p>了解了三者的通信方式,怎么能少了代码的描述!我们来看看代码如何实现。大致的实现步骤如下:</p> <p>(1)定义Module类,继承 ReactContextBaseJavaModule</p> <p>在Module类中,我们定义交互的方法,例如RN调用Native的方法,Native调用RN的方法等。</p> <p>(2)定义Package类,继承 ReactPackage</p> <p>实现Package的 createNativeModules 方法,将Module实例添加到集合。</p> <p>(3)定义Application,继承ReactApplication</p> <p>实现 getPackages方法 , 将Package实例添加到 getPackages 下的集合。</p> <p>1.Module类中的核心代码</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d43fbc52e98fc9ad1dda6cf50ca34423.png"></p> <p>名称可以自定义,对接时协商好即可。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/09a64509fd0e022e206fbbaca2168910.png"></p> <p>在module中定义一个方法,并用@ReactMethod 注解标注:表明该方法会被RN调用。即被RN调用的原生方法必须使用@ReactMethod注解标注。</p> <p>注意: RN层调用Native层进行界面跳转时,需要设置FLAG_ACTIVITY_NEW_TASK标志 ,否则会出现如下错误:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/db929cb307f0eaeb52518dbaff55add1.png"></p> <p>上面代码定义了原生方法,通过在Android层调用RN层。使用ReactContext的getJSModule方法,emit来发送消息。同样,emit的第一个参数要与RN层中addListener方法的第一个参数相同。</p> <p>2.自定义Package的核心代码</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/5297d16cb6da0a6faf6f356f56e77482.png"></p> <p>在createNativeModules方法中,初始化集合,并将module实例添加进集合,返回集合实例。</p> <p>3.Application核心代码</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/fe0e82af28b32f6e52c1b6c1fb7da5cc.png"></p> <p>在getPackages方法中,将Package实例添加到Arrays中即可完成注册。</p> <p>以上就是Android层核心代码配置,继续来看React Native层核心代码:</p> <p>1.调用原生代码</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/163552ba869b1aaad46ed13d9d9dd3b6.png"></p> <p>在React Native层,通过NativeModules调用commModule,继而调用原生方法即可。 注意:commModule要与Module类的getNames方法返回的名称对应。</p> <p>2. 接收原生调用</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/22e03e7cd23cb10331ac98554818466d.png"></p> <p>通过DeviceEventEmitter注册监听,类似于Android中的监听事件。第一个参数标识名称,要与Module中emit的Event Name相同。第二个参数即为处理回掉。</p> <p>3.界面代码</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/9f6a2697a0a033b9ed18c91c506ed90a.png"></p> <p>在Text中注册单击事件,RN层调用原生代码,跳转到拨号界面。</p> <p>4.Android层调用RN的代码</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/5b688299d5c9c0d2087191e382a3e854.png"></p> <p>调用Module中定义的nativeCallRn方法,继而出发RN层代码。以上就是通过 RCTDeviceEventEmitter 模式进行通信交互。可以很清晰的看出,交互都是以主动方式为主。</p> <p>RN中剩下的两种通信方式,存在一个共同的特点:</p> <p>从RN层调用Native层,Native层处理完成后,回调RN层</p> <p>直接看代码实现:</p> <p>(1)Callback</p> <p>同样还是在Module类中定义交互方法:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/01c4f662c74c39170807c0ebe5c1c25c.png"></p> <p>RN中定义回调:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/dab1d483cfa3e0732a6fb53b1caeefda.png"></p> <p>(2)Promise</p> <p>Module类中定义交互方法:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/54046fb947bffd853d7b51b0134f1ae1.png"></p> <p>RN中定义回调:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/1e18932c66fd5997cb3462ee02416469.png"></p> <p>布局中触发单击事件:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/f33915a1872ae16def5c8dd793ca13a9.png"></p> <p>最终效果:</p> <p>Android调用React Native:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/ed450978aebc64a10b787ecbd051d511.gif"></p> <p>React Native调用Android:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/274839943d189c4b3e792962cdcebbdd.gif"></p> <p> </p> <p> </p> <p>来自:http://blog.csdn.net/u013718120/article/details/55506238</p> <p> </p>