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