?前提是用react-native init 工程名 已經(jīng)初始化好一個(gè)可以正常運(yùn)行的RN工程(檢驗(yàn)標(biāo)準(zhǔn)是在手機(jī)上可以正常運(yùn)行)鸽凶。
下面的步驟是在RN0.17版本的,0.18版本后也是可以的齿椅,由于官方進(jìn)一步封裝文捶,具體步驟可能略有不同。
一媒咳、導(dǎo)入Android原生模塊的步驟
步驟1.新建java類繼承ReactContextBaseJavaModule.
public class MyToastModule extends ReactContextBaseJavaModule
必須復(fù)寫getName方法粹排,return后跟的是JS里要調(diào)用的名字(可不同于類名)。
public String getName() {
return "MyToastAndroid";
}
定義要被JS使用的方法涩澡,要加上注解@ReactMethod
@ReactMethod
public void show(){
Toast.makeText(getReactApplicationContext(),"hello",Toast.LENGTH_LONG).show();
}
步驟2.新建類實(shí)現(xiàn)ReactPackage接口
public class MyReactPackage? implements ReactPackage
有三個(gè)方法需要實(shí)現(xiàn):createNativeModeule,createJSModules,createViewManagers.這三個(gè)方法都返回list顽耳,
要注意一點(diǎn)是雖然默認(rèn)返回null,但這樣寫編譯時(shí)會(huì)出錯(cuò),要改寫成返回空集合射富,一般寫成
return Collections.emptyList();
此時(shí)需要在createNativeModeule里膝迎,返回帶有上面module的集合
@Override
public List createNativeModules(ReactApplicationContext reactContext) {
return Arrays.asList(
new MyToastModule(reactContext)
);
}
步驟3.在MainActivity里(在RN工程里是自動(dòng)生成的入口activity),添加上面的自定義的ReactPackage
mReactInstanceManager = ReactInstanceManager.builder()
胰耗。限次。。柴灯。//省略其他代碼
.addPackage(new MainReactPackage())
.addPackage(new MyReactPackage())
卖漫。。赠群。羊始。//省略其他代碼
步驟4.在JS里調(diào)用剛才的原生模塊
React.NativeModules.MyToastAndroid.show();
二、上面是最簡(jiǎn)單的一種調(diào)用查描,基本步驟是不變的突委,接下來(lái)是在上面基礎(chǔ)上多了點(diǎn)東西的調(diào)用。
1.在JS里調(diào)用帶參數(shù)的原生模塊里的方法
將上面的MyToastModule類里的show方法改為
@ReactMethod
public void show(String message,int dur){
Toast.makeText(getReactApplicationContext(),message,dur).show();
}
在JS里調(diào)用為
React.NativeModules.MyToastAndroid.show("hello",1);
2.在JS里調(diào)用原生模塊里的預(yù)設(shè)參數(shù)
在MyToastModule的Java類里復(fù)寫方法getConstants冬三,此方法返回了需要導(dǎo)出給JavaScript使用的常量
@Override? ? ? ? public Map getConstants() {? ? final Map constants = new HashMap<>();? ? ? ? ? ? constants.put("HAHA", Toast.LENGTH_SHORT);? ? ? ? ? ? constants.put("LONG", Toast.LENGTH_LONG);
return constants;? ? ? ? }
在JS里調(diào)用為
React.NativeModules.MyToastAndroid.show("hellohaha",React.NativeModules.MyToastAndroid.HAHA);
3.將原生模塊封裝成一個(gè)JS模塊匀油,以便省下每次都從NativeModules中獲取對(duì)應(yīng)模塊的步驟,從JS端訪問更為方便勾笆。
新建名為MyToastAndroidJS的JS文件钧唐,文件里內(nèi)容為
'use strict'
var {NativeModules} = require('react-native');
module.exports=NativeModules.MyToastAndroid;
在其他JS代碼或文件中可以這樣調(diào)用,
var MyToastAndroidLOL = require('./MyToastAndroidJS');//此處確保按文件路徑可以被查找到
MyToastAndroidLOL.show('haha JSModule',MyToastAndroidLOL.HAHA);
三匠襟、回調(diào)函數(shù)
上面全是JS調(diào)用原生模塊里的方法钝侠,有參或無(wú)參,但原生模塊只是被調(diào)用酸舍,沒有反饋回來(lái)數(shù)據(jù)帅韧,下面是回調(diào)使用說(shuō)明。(此處承接上面的3)
1.使用Callback回調(diào)
在MyToastAndroid中添加方法showAll啃勉。在showAll的參數(shù)中的callback是com.facebook.react.bridge.Callback忽舟,注意別導(dǎo)錯(cuò)包了。
@ReactMethod
public void showAll(int a,int b,Callback erroCallBack,Callback successCallback){
try{
int c=a/b;
successCallback.invoke(a,b);
}catch(Exception e){
erroCallBack.invoke(e.getMessage());
}
}
在JS中調(diào)用showAll方法
MyToastAndroidJJ.showAll(
1,2,
(msg) => {console.log(msg)},
(x,y) => {console.log(x+':'+y)}
);
運(yùn)行后logcat上會(huì)打印出1:2淮阐,
當(dāng)是
MyToastAndroidJJ.showAll(
1,0,
(msg) => {console.log(msg)},
(x,y) => {console.log(x+':'+y)}
);
運(yùn)行后logcat上會(huì)打印出 divide by zero等異常信息叮阅。
這樣就實(shí)現(xiàn)了原生模塊向JS傳遞數(shù)據(jù),并且其中有很大的自由度供調(diào)用實(shí)現(xiàn)泣特。但要注意showAll里的參數(shù)個(gè)數(shù)在被JS調(diào)用時(shí)是要一一對(duì)應(yīng)的浩姥,在MyToastAndroid中定義了幾個(gè)參數(shù)就要在JS中調(diào)用時(shí)提供幾個(gè)參數(shù)。
2.使用Promise回調(diào)
在MyToastAndroid中添加方法showB
@ReactMethod
public void showB(int a,int b,Promise promise){
try{
int c=a/b;
promise.resolve(a+b);
}catch(Exception e){
promise.reject("test:"+e.getMessage());
}
}
在JS中状您,聲明一個(gè)方法
showBInJS: async function (){
try{
var c = await MyToastAndroidJJ.showB(1,2);
console.log("test:"+c);
}catch(e){
console.log(e);
}
},
在JS中調(diào)用
this.showBInJS();
在log中會(huì)打印出 test:3勒叠。
把上面聲明中的2改為0兜挨,保存然后Reload JS。
在log中會(huì)打印出 test:divide by zero 等異常信息眯分。
上面是返回一個(gè)參數(shù)拌汇,下面是可以返回多個(gè)參數(shù)的方式(不唯一)
在MyToastAndroid中改寫方法showB
@ReactMethod
public void showB(int a,int b,Promise promise){
try{
int c=a/b;
WritableMap map = Arguments.createMap();
map.putInt("haha",a);
map.putInt("hehe",b);
promise.resolve(map);
}catch(Exception e){
promise.reject("fyp:"+e.getMessage());
}
}
在JS中改寫showBInJS的聲明
showBInJS: async function (){
try{
var {haha,hehe} = await MyToastAndroidJJ.showB(1,2);
console.log("test:"+haha+":"+hehe);
}catch(e){
console.log(e);
}
},
調(diào)用不變。
重新react-native run-android,在log里會(huì)打印出 test:1:2弊决。