Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Java本地调用JavaScript方法_Java_React Native - Fatal编程技术网

从Java本地调用JavaScript方法

从Java本地调用JavaScript方法,java,react-native,Java,React Native,我不熟悉React Native,但想知道是否可以从Java调用React Native JavaScript方法?我有一个小众设备,它有一个物理按钮,我想在按下时用它来触发一个方法 我看过下面的插件,但是Android的实现似乎已经过时了 我在谷歌上搜索过,但我能找到的所有示例都是从React Native调用Java方法的引用,而不是相反 非常感谢 编辑 我尝试使用下面@ide建议的方法实现一个解决方案。以下是我迄今为止的尝试: 在我的主要活动中,我有: private String lat

我不熟悉React Native,但想知道是否可以从Java调用React Native JavaScript方法?我有一个小众设备,它有一个物理按钮,我想在按下时用它来触发一个方法

我看过下面的插件,但是Android的实现似乎已经过时了

我在谷歌上搜索过,但我能找到的所有示例都是从React Native调用Java方法的引用,而不是相反

非常感谢

编辑

我尝试使用下面@ide建议的方法实现一个解决方案。以下是我迄今为止的尝试:

在我的主要活动中,我有:

private String latestBarcode = "";

...

public String getLastestBarcode() {
  return this.latestBarcode;
}

public void setLatestBarcode(String barcode) {
  this.latestBarcode = barcode;
}

@Override
public void onBarcodeEvent(final BarcodeReadEvent event) {
  runOnUiThread(new Runnable(){
    @Override
    public void run() {
      String barcodeData = event.getBarcodeData();
      String tstp = event.getTimestamp();
      setLatestBarcode(barcodeData);
      Log.d("MainActivity", " TEST - barcodeData "+ barcodeData + " tstp : "+ tstp);
    }
  });
}
...
当用户按下物理硬件按钮时,此代码从设备获取条形码值

在我的自定义反应本机模块中

@ReactMethod
public void latestBarcode(Callback callback) {
  final Activity activity = getCurrentActivity();

  if(activity != null && activity instanceof MainActivity){
    callback.invoke(((MainActivity) activity).getLastestBarcode());
  }
  else {
    callback.invoke("");
  }
}
此方法获取该值并将其公开为React Native。这是可行的,我可以读取值,但当用户按下按钮时,我需要触发一个方法,因此这是我的React本机模块,因为它现在是完整的:

import android.app.Activity;
import android.util.Log;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;

import javax.annotation.Nullable;

// Import MainActivity
import com.myapp.MainActivity;

public class HoneywellCT50Module extends ReactContextBaseJavaModule {
  private ReactContext reactContext;

  public HoneywellCT50Module(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
  }


  @ReactMethod
  public void latestBarcode(Callback callback) {
    final Activity activity = getCurrentActivity();

    if(activity != null && activity instanceof MainActivity){
      WritableMap params = Arguments.createMap(); // <--- Added WritableMap
      sendEvent("BarcodeRecieved", params); // <--- Added sendEvent

      callback.invoke(((MainActivity) activity).getLastestBarcode());
    }
    else {
      callback.invoke("");
    }
  }

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


  @Override
  public String getName() {
    return "HoneywellCT50";
  }
}

使用上面的代码,我可以构建没有Java/build错误的项目,也看不到JS错误,但我无法触发事件。有人能帮我指出正确的方向吗?

您要做的是从Java发出一个事件,并发送到JavaScript。您将编写一个自定义本机模块,从JavaScript订阅其事件,然后在本机代码中发出事件。请参阅本指南:

好的,因此我得到了一些代码。我不确定这是否是最好的解决方案,但目前我的理解有限,并欢迎对以下方面的任何反馈:

MainActivity.java

@Override
public void onBarcodeEvent(final BarcodeReadEvent event) {
  runOnUiThread(new Runnable(){
    @Override
    public void run() {
      String barcodeData = event.getBarcodeData();
      String tstp = event.getTimestamp();
      setLatestBarcode(barcodeData);
      Log.d("MainActivity", " TEST - barcodeData "+ barcodeData + " tstp : "+ tstp);
    }
  });

  WritableMap params = Arguments.createMap(); // <--- added

  getReactInstanceManager().getCurrentReactContext() // <--- added
    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) // <--- added
    .emit("BarcodeReceived", params); // <--- added
}

如果有经验的人读过这篇文章,我很想知道为什么我上面编辑的代码不起作用。是因为我尝试在
@ReactMethod
中发出事件吗?

@ide我尝试根据您的答案实现一个解决方案,并在上面添加了代码。你对我的错误有什么建议吗?@Guillermo Grau指出,在最新RN版本(至少44和45)的文档中,将事件从Java发送到JavaScript似乎已经不存在了。链接到旧文档:
@Override
public void onBarcodeEvent(final BarcodeReadEvent event) {
  runOnUiThread(new Runnable(){
    @Override
    public void run() {
      String barcodeData = event.getBarcodeData();
      String tstp = event.getTimestamp();
      setLatestBarcode(barcodeData);
      Log.d("MainActivity", " TEST - barcodeData "+ barcodeData + " tstp : "+ tstp);
    }
  });

  WritableMap params = Arguments.createMap(); // <--- added

  getReactInstanceManager().getCurrentReactContext() // <--- added
    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) // <--- added
    .emit("BarcodeReceived", params); // <--- added
}
componentWillUnmount () {
  this._barcodeListener.remove()
}

componentWillMount () {
  // Listen for Honeywell Scans
  this.getBarcodeValue = DeviceEventEmitter.addListener('BarcodeReceived', this.getBarcodeValue)
}

...

getBarcodeValue () {
  console.log('Event Received')

  HoneywellCT50.latestBarcode((value) => {
    this.setState({ barcode: value }, () => {
      console.log(this.state.barcode)
    })
  })
}