React Native学习(Android)——交互

交互的前提是你已经建立好了RN和Native,已经可以进行第一个Hello World。
React Native和Native之间的交互的前提是搭建一个Module和Package。Module可以理解为一个交流工具,它需要继承 ReactContextBaseJavaModule,我们写的一些交互方法全在这里面。Package它需要继承ReactPackage,主要是起个注册作用,将之前创建的Module添加到ReactNativeHost中,这样我们才能调用到。

建立Module

Module其中有两个方法实现,getName()是必须实现的,getConstants()自己看情况实现。

  1. getName方法是需要返回你这个Module的一个名称,用来标识这个Module,常返回这个类的类名,省事又简单。

     @Nonnull
     @Override
     public String getName() {
         return "MyRnModule";
     }
    
  2. getConstants方法是返回一个Map,官方的描述是:一个可选的方法,返回了需要导出给 JavaScript 使用的常量。它并不一定需要实现,但在定义一些可以被 JavaScript 同步访问到的预定义的值时非常有用。

     @Nullable
     @Override
     public Map<String, Object> getConstants() {
         HashMap<String, Object> constants = new HashMap<>();
         constants.put("keyName", "valueString");
     	...
         return constants;
     }
    
建立Package

Package其中有两个方法需要实现,createNativeModules()和createViewManagers()。这里将mModule放在外面,不要写成return modules(new MyRnModule(reactContext)),我们在后面需要调用方法,需要这个对象。

  1. createNativeModules方法是需要返回你需要注册的Module,上文的MyModule。

  2. createViewManagers方法是返回一个UIManagerModule的视图管理列表(UIManagerModule具体作用自行学习),这里我们返回一个空列表。

     public class MyRnPackage implements ReactPackage {
         public MyRnModule mModule;
         @Override
         public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
             List<NativeModule> modules = new ArrayList<>();
             mModule = new MyRnModule(reactContext);
             modules.add(mModule);
             return modules;
         }
     
         @Override
         public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
             return Collections.emptyList();
         }
     }
    
注册

在MainApplication的getPackages()中注册新建的Package。

public class MainApplication extends Application implements ReactApplication {

    private static final MyRnPackage myRnPackage = new MyRnPackage();

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
                    myRnPackage  // ====>	这里就是我们添加的地方
					//new MyRnPackage(); ===>不要写成这个样子,问你我们需要拿到这个reactPackage
            );
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, false);
    }

    /**
     * 获取 reactPackage
     */
    public static MyRnPackage getReactPackage() {
        return myRnPackage;
    }

}
RN向Native发送数据

例如RN需要打开某一个Activity页面就可以在Module中写如下:

/**
 * RN调用Native的方法
 */
@ReactMethod
public void StartActivity(String toActivity, String data) {
    try {
		// mReactContext:新建ReactApplicationContext mReactContext并在构造方法中赋值
        Intent intent = new Intent(mReactContext, Class.forName(mReactContext.getPackageName()+"."+toActivity));
        intent.putExtra("params", data);
		// FLAG_ACTIVITY_NEW_TASK必须要有,要不然会报错
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mReactContext.startActivity(intent);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

在跳转的页面onCreate()中可以接收传值:

Intent intent = getIntent();
if (intent != null) {
    String params = intent.getStringExtra("params");
    Log.e("信息:", "从react-native中传递过来的数据:" + params);
}
Native向RN发送数据

Native向RN发送数据,例如在Native获取设备的一些信息,转化为JSONString后发给React Native显示。
这里我们采用RCTDeviceEventEmitter方法来实现这一功能。RCTDeviceEventEmitter类似于Android原生中的广播,在MyModule中写如下代码:

/**
 * Native调用RN
 * RCTDeviceEventEmitter方法
 * flag:一个标识,类似广播中的intentFilter.addAction("xxx")
 * msg :传递的数据
 */
@ReactMethod
public void nativeCallRn(String msg) {
    mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit(flag, msg);
}

在js中接收数据,可以在componentDidMount()生命周期时进行数据获取

componentDidMount() {
	// 这里的flag和上面的flag需要一致
    DeviceEventEmitter.addListener(flag, (msg) => {
        text = msg
    })
}

在Activity中向RN发送数据:

/**
 * 参数介绍:
 * getReactPackage():MainApplication中获取MyRnPackage的方法
 * mModule:拿到Package后再拿到具体的MyModule
 * nativeCallRn():拿到Module后调用具体的方法
 */
MainApplication.getReactPackage().mModule.nativeCallRn("hello");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值