緣由
有時候App需要訪問平臺api,但在RN中沒有相應的模組,或者需要你複用一些原生程式碼,這就需要進一步開發RN原生模組。一般用React Native開發App時會用到一些原生模組,比如:在做社會化分享、第三方登入、掃描、通訊錄,日曆等等。
開發原生模組的主要流程
1. 編寫原生模組的Java或者ios程式碼;
2. js呼叫java原生程式碼與資料互動;
3. 註冊與匯出React Native原生模組;
複製程式碼
編寫原生模組的Java程式碼;
按照java規範,編寫相應的功能。比如QQ的分享功能。
js呼叫java原生程式碼與資料互動;
public class QQSDK extends ReactContextBaseJavaModule {
@Override
public String getName() {
return "QQSDK";
}
//釋放資源
@Override
public void onCatalystInstanceDestroy() {
super.onCatalystInstanceDestroy();
// ... 省略部分程式碼
}
@ReactMethod
public void shareText(String text,int shareScene, final Promise promise) {
// ... 省略部分程式碼
}
複製程式碼
繼承 ReactContextBaseJavaModule
,我們重寫了public String getName()
方法,來暴露我們原生模組的名字。並在 public void shareText(String text,int shareScene, final Promise promise)
上新增了@ReactMethod
註解來暴露介面,這樣以來我們就可以在js檔案中來通過shareText呼叫我們所暴露給React Native的介面了。
資料互動方式分三種:Promise,Callbacks,DeviceEventEmitter,注意:前2個我們只能呼叫一次,RCTDeviceEventEmitter,它是原生模組和js之間的一個事件發射器
//宣告:
public void shareText(String text,int shareScene, final Promise promise)
//js呼叫
QQ. shareText(”text“,
shareScene).
.then();
複製程式碼
//宣告:
public void shareText(String text,int shareScene, Callback errorCallback,Callback successCallback)
//js呼叫
Q. shareText(”text“,
shareScene,(error)=>{
console.log(error);
},(result)=>{
console.log(result);
})
複製程式碼
private void sendEvent(ReactContext reactContext,String eventName, @Nullable WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
複製程式碼
在上述方法中我們可以向js模組傳送任意次數的事件,其中eventName是我們要傳送事件的事件名,params是此次事件所攜帶的資料,接下來呢我們就可以在js模組中監聽這個事件了
componentDidMount() {
//註冊掃描監聽
DeviceEventEmitter.addListener('onScanningResult',this.onScanningResult);
}
onScanningResult = (e)=> {
this.setState({
scanningResult: e.result,
});
}
複製程式碼
另外,不要忘記在元件被解除安裝的時候移除監聽:
componentWillUnmount(){
DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult);//移除掃描監聽
}
複製程式碼
註冊與匯出React Native原生模組
- 只有我們註冊了剛才建立的原生模組,在js中才能呼叫,
只需實現ReactPackage
即可;模版程式碼:如下
public class QQSDKPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new QQSDK(reactContext));
return modules;
}
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
複製程式碼
- 然後匯出一個js模組,以方便我們使用它 建立一個qqindex’.js檔案,然後新增如下程式碼:
import {
NativeModules,
NativeEventEmitter
} from 'react-native';
const {QQSDK} = NativeModules;
export function shareText(text,shareScene) {
return QQSDK.shareText(text,shareScene);
}
複製程式碼
- 接下來就可以在js中使用我們匯出的程式碼了
Q. shareText(”text“,
shareScene,(error)=>{
console.log(error);
},(result)=>{
console.log(result);
})
複製程式碼