React Native调用原生模块返回null怎么办?
我在React Native项目里写了个原生模块想获取设备信息,但调用方法总是返回null。按照官方文档写了Java代码并注册了模块,但前端调用的时候就是得不到正确数据…
这是我的React代码片段:
import React, { Component } from 'react';
class DeviceInfo extends Component {
async componentDidMount() {
const message = await NativeModules.DeviceModule.getDeviceInfo();
this.setState({ deviceInfo: message }); // 这里得到null
}
render() {
return 设备信息:{this.state.deviceInfo}
;
}
}
我已经确认原生模块在Android里的implementation方法确实返回了字符串,也检查了模块名拼写。但模拟器运行时显示null,有没有可能是模块注册的问题?或者需要特别配置metro bundler?
先说最可能的原因:你确认原生模块注册了吗?Android端写完模块后,必须在MainApplication的getPackages()方法里把模块加进去,不然前端怎么调都是null。
看一下你的Java代码大概长这样:
注意几个点:
第一,方法必须加@ReactMethod注解,不加的话前端根本看不到这个方法。
第二,返回值要用Promise,不能直接return字符串。React Native的桥接是异步的,你用await是对的,但原生端必须用promise.resolve()来返回数据。
第三,检查一下前端调用方式。你用的是await NativeModules.DeviceModule.getDeviceInfo(),模块名是DeviceModule不是你代码里的DeviceInfo,这个别搞混了。
还有一种可能是新架构的问题。如果你用的是最新版本的React Native,默认开启了新架构,原生模块注册方式不一样,得用TurboModule。你可以试试在原生代码里加个打印log,确认方法到底有没有被调用。
最后提醒一下,模拟器有些特性可能不支持,比如某些硬件信息获取,如果你是用模拟器测试的话可以考虑换真机试试。
1. 首先确认下Java那边的返回值是不是标准的JSON格式或者String类型,如果不是,React Native可能解析不了。
2. 然后看看是否正确实现了
@ReactMethod注解的方法,并且注意这个方法必须是void类型,不能直接返回值,需要用回调或者Promise。你可以改一下你的Java代码,像这样写:
接着前端代码也要稍微调整下,改成这样:
最后记得清理下项目缓存再跑一遍:
cd android && ./gradlew clean然后重新启动 metro bundler 和应用。
如果还是有问题,可能是包名或者模块名拼写有误,仔细检查下。改一下就行,别太纠结。