RN 與android原生互動

zhulk發表於2018-01-17

緣由

有時候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);
})

複製程式碼

如有疏漏,請指出,如有問題可以通過如下方式聯絡我

簡書 csdn 掘金 klvens跑碼場

相關文章