转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7275897.html

ReactNative可以用来进行一些嵌入式设备的操作终端开发,比如:ATM机、自动售卖机等。其中,最重要的一步是,怎样在ReactNative所在设备,进行一系列硬件上的操作,比如:售卖机出货、ATM机吐钱?

一:底层操作串口包装

对于机器的控制,ReactNative本身当然不可能做到。这些底层的操作一般都是用C/C++来实现的。而我们要做的,是把这些C/C++函数,包装成java接口,导出为aar文件。(注意:*.jar:只包含了class文件与清单文件,不包含资源文件,如图片等所有res中的文件。*.aar:包含所有资源,class以及res资源文件全部包含)

对于底层的操作,我们不需要关心,由厂商提供或者负责嵌入式开发的人来定义。

在ReactNative中调用aar分为两部分:首先是通过原生Android代码调用aar中的接口,包装成为可供ReactNative调用的方法;然后在ReactNative代码中调用Android代码中的对应方法。

二:Android调用aar

1:首先,我们把aar文件放到项目的android目录的一个文件夹中,比如:新建一个libs文件夹。

2:然后,在android目录下的build.gradle文件中添加这个aar包路径:

allprojects {
repositories {
mavenLocal()
flatDir{
dirs "$rootDir/libs" //在这里加上这句
 } ...... } }

3:在android/app目录下的build.gradle文件中依赖这个aar包

dependencies {
......
compile(name:'aar包名', ext:'aar')//加上这句
}

4:然后,就可以在android/app/src/main/java/com/xx目录下新建java类,在类中  import aar包名.类名  即可使用aar包中的各种接口。

附:如何打开、查看aar文件内容,获取其中类、接口的信息?

修改aar文件后缀为  zip  ,然后解压它,可以得到一个classes.jar文件。

使用java反编译工具即可查看classes.jar包中的内容,获取供我们调用的接口信息。

三:ReactNative中的原生Android开发

1:定义原生模块,调用aar文件

在android/app/src/main/java/com/xx目录下,新建一个类文件。

定义继承ReactContextBaseJavaModule的Java类

import aar包名.aar中类名

import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise; public class 模块类 extends ReactContextBaseJavaModule {
public 模块类(ReactApplicationContext reactContext) {
super(reactContext);
} // 要求重写getName方法,返回一个字符串作为这个原生模块名,用于在JavaScript端标记、使用这个模块
@Override
public String getName() {
return "模块名";
} // 定义供JavaScript调用的方法,需要使用注解@ReactMethod,返回值是void!
@ReactMethod
public void 方法名() {
通过 aar中类名.方法名() 调用aar中接口。
}
。。。。。。
}

2:注册模块

在模块类文件同级目录下,新建一个  模块名Package.java  的类文件,重写几个方法:

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; public class 模块名Package implements ReactPackage { public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
} @Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
} @Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>(); modules.add(new 模块类(reactContext));/添加模块
return modules;
}
}

3:在IDE自动创建好的android/app/src/main/java/com/项目名   目录下的MainApplication.java中添加Package实例

    @Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new 模块名Package() //在这里添加package实例
);
}

4:另外,也可以在android/app/src/main/java/com/项目名   目录下自动创建的MainActivity类中定义一些随着app生命周期而触发的方法。比如:onCreate()等等Android原生Activity生命周期函数。

四:在ReactNative的js文件中调用原生Android模块内方法

1:导入本地模块库

在js文件头导入本地模块库

import { NativeModules } from 'react-native';

2:通过 NativeModules.模块名.方法名() 进行本地模块内函数的调用

3:获取调用结果

提供给js调用的原生android方法的返回类型必须是void,所以想要给JavaScript返回一个值的唯一办法是使用回调函数或者发送事件。

使用回调函数:

1)android代码中定义的方法,传进回调函数作为参数

  // android端代码
@ReactMethod
public void 方法名(...参数,Callback callback){
......
callback(...);//调用回调函数
}

2)js端调用方法时,除了传递数据参数,还传递回调函数获取调用结果

// RN端调用代码
NativeModules.模块名.方法名(...参数,(回调函数参数)=>{回调函数体)});

使用Promise发送异步任务状态进行回调:

向模块方法传递数据一个promise对象,模块方法中通过promise返回执行状态以达到反馈执行结果的目的:

1)android端

// android端代码
@ReactMethod
public void 方法名(数据参数, Promise promise){
try{
if(...){
promise.resolve(map);//正常返回,并且携带返回结果
}else{
promise.reject(结果信息);//返回另一种结果
}
}catch(IllegalViewOperationException e){
promise.reject(异常信息);//异常退出
}
}

2)js端:传递一个匿名promise对象参数,使用 then(resolveCallBack,rejectCallBack) 来接受返回结果并执行相应回调函数

NativeModules.模块名.方法名(数据参数,new Promise().then((resolve状态返回值)=> {提取结果}, (reject状态返回值)=> {提取结果});

ReactNative调用aar文件(附:如何打开、查看aar文件内容)的更多相关文章

  1. 用UltraEdit判断打开文件的编码类型 用UltraEdit或notepad记事本查看文件编码格式 用UltraEdit查看当前文件编码

    用UltraEdit查看当前文件编码 想判断文件的编码类型? 用强大的UltraEdit-32软件: UltraEdit-32的状态栏可以显示文件的编码类型,详细情况如下: ANSI/ANSCI--- ...

  2. 打开窗口进行选择文件(txt文件),打开所选文件,读入文件

    用mfc编写项目的时候往往需要调用窗口,允许用户通过窗口进行选择文件操作 TCHAR szBuffer[MAX_PATH] = { 0 }; OPENFILENAME ofn = { 0 }; ofn ...

  3. 如何将SolidWorks文件另存为.obj文件及如何打开.obj格式文件

    原网站:http://fans.solidworks.com.cn/forum.php?mod=viewthread&tid=40238) OBJ文件是Alias Wavefront公司为它的 ...

  4. C#用openfiledialog文件和savefileDialog打开和保存文件

    一 打开文件 Stream myStream = null; OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog ...

  5. #用openfiledialog文件和savefileDialog打开和保存文件

    一.打开文件 Stream myStream = null;            OpenFileDialog openFileDialog1 = new OpenFileDialog();     ...

  6. Temporary ASP.NET Files 文件夹中保存的是什么内容?[转]

    转自:http://www.cnblogs.com/suiqirui19872005/archive/2007/05/14/746320.html ASP.NET 页面请求的处理过程需要使用一些临时文 ...

  7. php 写内容到文件,把日志写到log文件

    php 写内容到文件,把日志写到log文件 <?php header("Content-type: text/html; charset=utf-8"); /******** ...

  8. 文件包含之包含了Linux文件描述符

    0x00 原理   文件描述符是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符. 翻译成人话- 可以认为是指向文件的一个指针,如果有文件 ...

  9. 解决svn:E155037错误(另附查看.db文件的工具)

    今天使用svn提交代码的时候出问题了,Error:svn: E155037.....Previous operation has not finished; run 'cleanup' if it w ...

随机推荐

  1. zoj2334 Monkey King , 并查集,可并堆,左偏树

    提交地址:点击打开链接 题意:  N(N<=10^5)仅仅猴子,初始每仅仅猴子为自己猴群的猴王.每仅仅猴子有一个初始的力量值.这些猴子会有M次会面. 每次两仅仅猴子x,y会面,若x,y属于同一个 ...

  2. 高速Android开发系列通信篇之EventBus

    概述及基本概念 **EventBus**是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信.比方请求网络,等网络返回时通过Hand ...

  3. .NET零基础入门09:SQL必知必会

    一:前言 仿佛到了更进一步的时候了,每一个程序员迟早都会遇到数据存储的问题.我们拿什么来存储程序产生的数据?举例来说,用什么来存储我们的打老鼠游戏每次的成绩呢?选择如下: 1:内存中.缺点,退出游戏, ...

  4. 关于CSS中的float可能出现的小问题

    关于CSS中的float可能出现的小问题 前言:最近学习CSS的float所遇到点小问题,然后顺便分享给大家. 一.什么是CSS以及float (一) CSS概述 CSS是层叠样式表(英文全称:Cas ...

  5. [转]PHP 真正多线程的使用

    From : http://blog.s135.com/pthreads/ PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程.多线程在处理重复性的循环任务,能够 ...

  6. JavaScript-undefined与null区别

    JavaScript中的null在其他编程语言中也很常见,但是JavaScript在设计的过程中null自动转换为0,为了更好表示空,这个时候undefined出现了,null通过typeof结果是“ ...

  7. iOS开发-UIRefreshControl下拉刷新

    下拉刷新一直都是第三库的天下,有的第三库甚至支持上下左右刷新,UIRefreshControl是iOS6之后支持的一个刷新控件,不过由于功能单一,样式不能自定义,因此不能满足大众的需求,用法比较简单在 ...

  8. extern外部方法使用C#简单例子

    外部方法使用C#简单例子 1.增加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...

  9. 创建SQL作业错误的解决方法(不能将值 NULL 插入列 'owner_sid',表 'msdb.dbo.sysjobs';列不允许有空值。)

    在用SQL语句创建SQL Server作业时有时出现如下错误: 消息 515,级别 16,状态 2,过程 sp_add_job,第 137 行 不能将值 NULL 插入列 'owner_sid',表  ...

  10. android 框架层 常用类介绍

    名称 功能描述 示意图 activitymanager 管理应用程序的周期并提供常用的回退功能 window manager 窗口管理者 content provider 用于访问另一个的数据,或者共 ...