React Native 和Android交互

226 阅读1分钟

一、新建XXModule 继承ReactContextBaseJavaModule

public class TestModule extends ReactContextBaseJavaModule {

  public TestModule(@Nullable ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @NonNull
  @Override
  public String getName() {
		// 注意此处的防范名要和JS对应
    return "TestModule";
  }
}

二、新建XXPackage 实现ReactPackage

public class TestPackage implements ReactPackage {
  @NonNull
  @Override
  public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
    // 新建List
    List<NativeModule> modules = new ArrayList<>();
    // 添加刚才创建的XXModule
    modules.add(new XXModule(reactContext));
    return modules;
  }

  @NonNull
  @Override
  public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
    // 默认写法
    return Collections.emptyList();
  }
}

三、注册package(在项目的MainApplication中)

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() {
        @SuppressWarnings("UnnecessaryLocalVariable")
        List<ReactPackage> packages = new PackageList(this).getPackages();
				// 注册自定义的package
        packages.add(new TestPackage());
        // Packages that cannot be autolinked yet can be added manually here, for example:
        // packages.add(new MyReactNativePackage());
        return packages;
      }

      @Override
      protected String getJSMainModuleName() {
        return "index";
      }
    };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

四、定义方法

public class TestModule extends ReactContextBaseJavaModule {

  public TestModule(@Nullable ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @NonNull
  @Override
  public String getName() {
    // 注意此处的防范名要和JS对应
    return "TestModule";
  }

 //自定义的方法(注意必须添加注解)
  @ReactMethod(isBlockingSynchronousMethod = true)
  //==方法名也需要对应
  public void openFaceRecognition() {
    Toast.makeText(getCurrentActivity(), "打开人脸识别成功~", Toast.LENGTH_SHORT).show();
  }

 // 需要其他方法的话 继续在下面添加
 //@ReactMethod()
 //public void xxx(){}
}

五、JS端调用

import { NativeModules} from 'react-native';
// 注意此处名称必须和XXXModule中定义的名称对应,即函数getName的返回值
const { TestModule } = NativeModules;
<TouchableOpacity onPress={() => {
          TestModule.openFaceRecognition();
        }}>
          <View style={{
            width: 150,
            height: 45,
            backgroundColor: 'red',
            marginTop: 30,
            justifyContent: 'center',
            alignItems: 'center',
            borderRadius: 5,
          }}>
            <Text>Call Android method</Text>
          </View>
 </TouchableOpacity>

五、数据传递

  • 回调函数 Android 端
@ReactMethod
public void setName(String name, Callback onSuccess, Callback onError) {
  try {
    if (name != null) {
      //
      onSuccess.invoke("success");
    }
  } catch (Exception exception) {
    onError.invoke(exception.getMessage());
  }
}

JS端

TestModule.setName("name", (res) => {

}, (err) => {

})
  • promise Android 端
@ReactMethod
public void setName(String name, Promise promise) {
  try {
    if (name != null) {
      //
      promise.resolve("success");
    }
  } catch (Exception exception) {
    promise.reject("error", exception.getMessage());
  }
}

JS端

TestModule.setName("name").then(res=>{

console.log(res);

})
  • 事件监听

    JS 端添加事件的监听

    constructor(props: any) {
        super(props);
        this.state = {
          name: '',
        };
        DeviceEventEmitter.addListener('customEventName', this.eventCallback);
      }
    
      /**
       *
       * @param e
       */
      eventCallback = (e: Event) => {
        console.log(e);
        this.setState({
          name: e.name,
        });
      };
    

    Android端发送事件

    try {
          reactApplicationContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit("customEventName", map);
        } catch (Exception e) {
          Log.e("ReactNative", "Caught Exception: " + e.getMessage());
        }