Передача непрерывного обратного вызова с родного Android на компоненты react native

#react-native-android

#react-native

Вопрос:

я разрабатываю приложение для сканирования штрих-кодов для устройства с операционной системой Android.На этом устройстве motorola предоставляет SDK для сканирования штрих-кода и получения данных. я написал приложение react native для рендеринга моего пользовательского интерфейса и родной Android для получения штрих-кода.Теперь я хочу делать что-то вроде каждый раз, когда родной Android получает отсканированные данные в качестве обратного вызова из motorola sdk, он должен передавать их в rect native.Я попробовал метод обратного вызова, но обратный вызов может быть вызван только один раз собственным модулем, который не будет работать для меня, поскольку элемент будет сканироваться несколько раз.

Ответ №1:

К сожалению, это не слишком хорошо описано в официальных документах. Мне нравится добавлять этот метод ко всем моим соединенным модулям

 private void sendEvent(String eventName, @Nullable WritableMap params) {
        getReactApplicationContext()
               .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
               .emit(eventName, params);
    }
  

Параметры могут быть разных типов. Вот как они сопоставляются с Java на JS

 Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
WritableMap -> Object
WritableArray -> Array
  

Используйте эту функцию, когда вы хотите передать и событие для React Native из собственного кода. Если вы хотите передать массив или объект в качестве параметров, вам придется заранее создать WritableMap или WritableArray

Пример:

 public void emitInfo() {
   infoMap = Arguments.createMap();
   infoMap.putString("name", "dooley-doo");
   infoMap.putInt("version", 16);
   infoMap.putBoolean("isTrustworthy", False);
   sendEvent('INFO_EVENT', infoMap);
}
  

А затем в JS вы можете подписаться на это событие следующим образом:

 const eventEmitter = new NativeEventEmitter(NativeModules.myModule);
this.subscription = eventEmitter.addListener('INFO_EVENT',(params)=>console.log(params));          
  

А затем, когда вы закончите, отпишитесь вот так: this.subscription.remove();

Комментарии:

1. Записываемая карта не найдена

2. @Hitesh Sahu: импортируйте com.facebook.react.bridge. WritableMap;

3. @HiteshSahu Я знаю, что уже поздно, но это WritableMap не WriteableMap так. Проверьте орфографию.

Ответ №2:

Добавьте эти строки в свой index.android.js файл

     import {NativeEventEmitter } from 'react-native';

   class ReactNativeExample extends Component {
       constructor(props) {
           super(props);
           this.subscription = null;
          ....
       }

        componentDidMount() {
        const EVENT_NAME = new NativeEventEmitter(NativeModules.ChatMessageManager);
        this.subscription = EVENT_NAME.addListener(
                                 'EVENT_TAG',
                                 (message) => {
                                //Your logic
                                 });
    }

    componentWillUnmount() {
        this.subscription.remove();
    }

}
  

И в Android, откуда бы вы ни хотели отправлять данные с родного Android на react native JS, вызовите это

 reactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("EVENT_TAG", "PASS YOUR OBJECT");
  

Ответ №3:

Ответы, упомянутые выше, очень помогли. В моем случае я определил reactContext в MainActivity.java как

 ReactInstanceManager mReactInstanceManager = getReactNativeHost().getReactInstanceManager();
        ReactApplicationContext reactContext = (ReactApplicationContext) mReactInstanceManager.getCurrentReactContext();
  

и передал его через

 private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }
  

Надеюсь, это полезно.