有的时候我们使用React Native无法满足一些使用特定场景,这个时候就需要使用原生的Android方法,比如一些耗时的写操作,操作数据库或者多线程操作等。React Native可以直接调用系统的API(java方法),实现JavaScript与java语言的通讯,如果React Native中没有满足我们需求的Api,可以封装原生的方法提供JavaScript调用。
JavaScript和java通信是通过bridge实现的,在java层和JavaScript层的bridge分别存有相同的一份模块配置表。Java与JavaScript相互通信时,通过bridge里的配置表将所调用模块方式转为{moduleID,methodID,args}的形式传递给处理层,处理层通过bridge里的配置表找到对应的方法执行,如果有callback,则回传给调用层,如果没有执行就结束。

我们通过JavaScript调用Toast的例子来看下,JavaScript如何调用Java代码的。

新建一个项目:

react-native init app
在android的项目目录下面新建一个类RNToastModule,此类需要继承ReactContextBaseJavaModule。

ReactContextBaseJavaModule
ReactContextBaseJavaModule是一个抽象类,是用来被JavaScript调用对象的父类,我们需要Override一些ReactContextBaseJavaModule的方法。

首先要Override getName()方法:

   @Override   public String getName() {       return "RNToastAndroid";   }

这个方法的返回值就是JavaScript中调用的名称,比如我们命名为RNToastAndroid,在JavaScript中可以这样调用:

var {NativeModules}=require('react-native');var rnToastAndroid = NativeModules.RNToastAndroid;

在JavaScript可以这样调用:

rnToastAndroid.show("我的万能JS",  function (args) {            alert(args)        });

最后我们定义一个React调用的方法:

     @ReactMethod    public void show(String msg, Callback callback){        Toast.makeText(getReactApplicationContext(),"Js调用显示原生传递的参数是:"+msg,Toast.LENGTH_LONG).show();        callback.invoke("RNToastModule 调用JS方法");    }

完整RNToastModule代码:

/******************************** Copyright (c)*********************************\****                 (c) Copyright 2015, Allen, china, shanghai**                          All Rights Reserved****                          **                         **-----------------------------------版本信息------------------------------------** 版    本: V0.1****------------------------------------------------------------------------------********************************End of Head************************************\*/package com.app;import android.widget.Toast;import com.facebook.react.bridge.Callback;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;/** * 文 件 名: RNToastModule * 创 建 人: Allen * 创建日期: 17/1/2 23:17 * 邮   箱: AllenCoder@126.com * 修改时间: * 修改备注: */public class RNToastModule extends ReactContextBaseJavaModule{    public RNToastModule(final ReactApplicationContext reactContext) {        super(reactContext);    }    @Override    public String getName() {        return "RNToastAndroid";    }    @ReactMethod    public void show(String msg, Callback callback){        Toast.makeText(getReactApplicationContext(),"Js调用显示原生传递的参数是:"+msg,Toast.LENGTH_LONG).show();        callback.invoke("RNToastModule 调用JS方法");    }}

这个使用了annotation定义的方式必须加上@ReactMethod。
这里的参数只能React Navive定义的参数。

注册ReactPackage
新建一个JsReactPackage类,继承ReactPackage。

/******************************** Copyright (c)*********************************\****                 (c) Copyright 2015, Allen, china, shanghai**                          All Rights Reserved****                          **                         **-----------------------------------版本信息------------------------------------** 版    本: V0.1****------------------------------------------------------------------------------********************************End of Head************************************\*/package com.app;import com.facebook.react.ReactPackage;import com.facebook.react.bridge.JavaScriptModule;import com.facebook.react.bridge.NativeModule;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.uimanager.ViewManager;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * 文 件 名: JsReactPackage * 创 建 人: Allen * 创建日期: 17/1/2 22:34 * 邮   箱: AllenCoder@126.com * 修改时间: * 修改备注: */public class JsReactPackage implements ReactPackage {    @Override    public List createNativeModules(final ReactApplicationContext reactContext) {        List modules = new ArrayList<>();        modules.add(new RNToastModule(reactContext));        return modules;    }    @Override    public List> createJSModules() {        return Collections.emptyList();    }    @Override    public List createViewManagers(final ReactApplicationContext reactContext) {        return Collections.emptyList();    }}

JsReactPackage创建了一个NativeModule的List。把JsReactPackage的实例都添加进去提供给JavaScript层调用。

需要在Application中实例化。
首先实现新建一个ReactNativeHost的实例并添加RNJavaReactPackage的实例:

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {    @Override      protected boolean getUseDeveloperSupport() {          return BuildConfig.DEBUG;      }    @Override      protected List getPackages() {          return Arrays.asList(                new MainReactPackage(),                 //加入此处                       new JsReactPackage()                );      }};

JavaScript中调用
在JavaScript显示Toast:

'use strict';var {NativeModules}=require('react-native');var rnToastAndroid = NativeModules.RNToastAndroid;rnToastAndroid.show("我的万能JS",  function (args) {            alert(args)        });

这样就完成了从JavaScript中直接调用了Java中定义的方法。

参考链接

  1. https://segmentfault.com/a/1190000004486024
  2. http://blog.csdn.net/yuetingzhuying/article/details/51944254

更多相关文章

  1. Android(安卓)UI开发 View自绘控件 分享
  2. Android(安卓)Activity之间切换出现短暂黑屏的处理方法
  3. android横竖屏切换(复制未整理)
  4. Android大图加载方法
  5. android 自定义View之SubmitView
  6. Android(安卓)开发杂记
  7. android:GLSurfaceView绘制bitmap图片及glViewport调整的效果
  8. android单元测试AndroidTestCase
  9. 重温Android四大组件(一)—Activity的生命周期

随机推荐

  1. Android应用程序消息处理机制(Looper、Han
  2. Android(安卓)Studio更新以及异常处理【s
  3. 在Android中如何通过点击edittext之外的
  4. Android中使用SQLiteOpenHelper对SQLite
  5. android studio下Maven管理android的库
  6. android事件薄-不能安装APK的一种原因
  7. 取代opencore的stagefright
  8. Android(安卓)几种常用关于屏幕操作的方
  9. Android(安卓)网络管理
  10. :Android完全关闭应用程序