react-native可以做web与原生的交互,这是使用react-native开发项目的主要目的之一,也是主要优势,用rn而不用原生交互则毫无价值,这篇文章用来记录在项目中rn的原生交互使用过程。

之前说过要做的是一个pda项目,所以今天以input获取焦点的时候禁止软键盘弹出为例,大体说一下rn的原生交互过程。

android的原生交互分为以下几步

  1. 编写原生代码
  2. 向js暴露原生接口
  3. 注册原生模块
  4. 导出并再rn导入原生,模块

1、编写原生模块

作为web工程师出身的我,对原生android代码是不太了解的,充其量也只是稍微了解点java语言,但是通过自己的努力,还是过来了(笑哭);根据需求,就是再刚一进入页面的时候,让第一个input获取焦点,并同时隐藏软键盘,前端代码很好写,就是在获取焦点之后调用隐藏软键盘的原生功能;搞清楚了需求之后就开始编写原生代码了。

如上图,在newpda目录下面新建BoardModule类文件,用来编写原生功能代码;这个类继承自 ReactContextBaseJavaModule,代码如下

package com.newpda;
import android.util.Log;
import android.widget.Toast;
import android.widget.EditText;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.lang.reflect.Method; import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.app.Activity;
import android.app.ActivityManager;
import android.view.inputmethod.InputMethodManager;
import com.facebook.infer.annotation.Assertions;
import javax.annotation.Nullable; /**
* Description: Created by song on 2018/7/3. email:gaosongai@foxmail.com
*/
public class BoardModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
public BoardModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext; // 获取上下文
} @Override
public String getName() {
return "BoardModule";
} /**
*    关闭Edittext软件盘,光标依然正常显示。 
*/
@ReactMethod
public void hideboard() {
Activity currentActivity = getCurrentActivity();
InputMethodManager mInputMethodManager = (InputMethodManager)
Assertions.assertNotNull(this.reactContext.getSystemService(Context.INPUT_METHOD_SERVICE));
mInputMethodManager.hideSoftInputFromWindow(currentActivity.getCurrentFocus().getWindowToken(), 0);
}
}

hideboard为隐藏软键盘的方法,并向js暴露hideboard方法,要导出一个方法给JavaScript使用,Java方法需要使用注解@ReactMethod

2、注册模块

然后注册原生模块,同级目录下新建CustomBoardPackage类,代码如下

package com.newpda;

import com.facebook.react.ReactPackage;
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; /**
* Description:
* Created by song on 2018/9/6.
* email:gaosongai@foxmail.com
*/
public class CustomBoardPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules=new ArrayList<>();
modules.add(new BoardModule(reactContext));
return modules;
} @Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

我们需要在应用的Package类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在JavaScript中被访问到。

然后这个package需要在MainApplication.java文件的getPackages方法中提供,文件在同级目录下,代码如下

package com.newpda;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader; import java.util.Arrays;
import java.util.List; public class MainApplication extends Application implements ReactApplication { 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(),
new CustomBoardPackage() // 刚刚添加的方法
);
} @Override
protected String getJSMainModuleName() {
return "index";
}
}; @Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
} @Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}

3、在rn中引入模块

为了让你的功能从JavaScript端访问起来更为方便,通常我们都会把原生模块封装成一个JavaScript模块。这不是必须的,但省下了每次都从NativeModules中获取对应模块的步骤。这个JS文件也可以用于添加一些其他JavaScript端实现的功能,App.js同级目录下新建androidtoast.js,内容如下

import {NativeModules} from 'react-native';
module.exports = NativeModules.BoardModule;

然后在组件内部使用

import BoardModule from "../../../androidtoast";
BoardModule.hideboard(); // 使用原生模块方法

(五)react-native开发系列之Android原生交互的更多相关文章

  1. React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发

    React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发   2016/09/23 |  React Native技术文章 |  Sky丶清|  4 条评论 |  1 ...

  2. React Native开发入门

    目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料   一.前言 虽然只是简单的了解了一下Reac ...

  3. 【转】【React Native开发】

    [React Native开发]React Native控件之ListView组件讲解以及最齐全实例(19)  [React Native开发]React Native控件之Touchable*系列组 ...

  4. React Native开发 - 搭建React Native开发环境

    移动开发以前一般都是原生的语言来开发,Android开发是用Java语言,IOS的开发是Object-C或者Swift.那么对于开发一个App,至少需要两套代码.两个团队.对于公司来说,成本还是有的. ...

  5. React Native开发技术周报2

    (1).资讯 1.React Native 0.22_rc版本发布 添加了热自动重载功能 (2).技术文章 1.用 React Native 设计的第一个 iOS 应用 我们想为用户设计一款移动端的应 ...

  6. React Native开发技术周报1

    (一).资讯 1.React Native 0.21版本发布,最新版本功能特点,修复的Bug可以看一下已翻译 重要:如果升级 Android 项目到这个版本一定要读! 我们简化了 Android 应用 ...

  7. 深入浅出 React Native:使用 JavaScript 构建原生应用

    深入浅出 React Native:使用 JavaScript 构建原生应用 链接:https://zhuanlan.zhihu.com/p/19996445 原文:Introducing React ...

  8. Hybrid App 和 React Native 开发那点事

    简介:Hybrid App(混合模式移动应用)开发是指介于Web-app.Native-App这两者之间的一种开发模式,兼具「Native App 良好用户交互体验的优势」和「Web App 跨平台开 ...

  9. 《React Native 精解与实战》书籍连载「Node.js 简介与 React Native 开发环境配置」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

随机推荐

  1. 百度开源上传组件webuploader 可上传多文件并带有进度条

    //上传多文件 function UploadMultiFile() { var uploader = WebUploader.create({ // 选完文件后,是否自动上传. auto: true ...

  2. android -------- LiveDataBus的使用

    LiveData是17年GoogleIO大会上提出来的一个新技术.相对于通信总线类型的框架EventBus和RxBus来说,它更简单,更简洁.更解耦. LiveEventBus是一款Android消息 ...

  3. [转]Vue CLI 3搭建vue+vuex 最全分析

    原文地址:https://my.oschina.net/wangnian/blog/2051369 一.介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@ ...

  4. Python装饰器之functools.wraps的作用

    # -*- coding: utf-8 -*- # author:baoshan def wrapper(func): def inner_function(): pass return inner_ ...

  5. 屠龙术&平凡的世界

    x 听过很多道理,却依然过不好这一生 小时候,总觉得世上肯定存在屠龙术.就像<倚天屠龙记>里面张无忌学的<乾坤大挪移>/<九阳真经>一般, 学会了就可以一人单挑光明 ...

  6. Python进阶之面向对象

    新式类与旧式类 区别: 在2.2版本之前所有的类都是旧式类,3.x版本已取消旧式类 旧式类一般的写法,不继承任何父类 class Person: def __init__(self, name): s ...

  7. Python Tkinter 之Listbox控件

    Listbox为列表框控件,它可以包含一个或多个文本项(text item),可以设置为单选或多选.使用方式为Listbox(root,option...). 常用的参数列表如下: 一些常用的函数:

  8. python 之 网络编程(基于TCP协议的套接字通信操作)

    第八章网络编程 8.1 基于TCP协议的套接字通信 服务端套接字函数 s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连 ...

  9. Python进阶:GIL(全局解释器锁)

    一个不解之谜 一段代码 def CountDown(n): while n > 0: n -= 1 # CountDown(100000000) #==8秒 from threading imp ...

  10. DNS欺诈的三种简单方法总结

    使用arpspoof.ettercap以及driftnet的简单组合. ①arpsppof+driftnet arpspoof -i eth0 -t 目标ip 目标网关 driftnet -i eth ...