Use AndroidStudio to open the android directory in the project:
And wait for the Gradle Build to complete, the first Build will take a lot of time, wait patiently!
After successful compilation, as shown in the figure:
First, let's introduce js to call the native method:
1. Create new folders mymoudles and myreactpackage;
2. Create a new class ToastMoudle in mymoudles;
public class ToastModule extends ReactContextBaseJavaModule {
private ReactApplicationContext mContext;
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
mContext = reactContext;
}
@Override
public String getName() {
return "Toast";
}
@ReactMethod
public void show(String msg) {
Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
}
}
3. Create a new class MyReactPackage in myreactpackage;
public class MyReactPackage implements ReactPackage {
static ReactApplicationContext reactContext;
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
MyReactPackage.reactContext = reactContext;
List<NativeModule> modules = new ArrayList<>();
modules.add(new ToastModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
public static void sendEvent(String eventName, String params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
}
}
4. In the getPackages method of MainApplication, add MyReactPackage:
Tested in React's PageOne:
import {
NativeModules,
...
} from 'react-native';
testNativeFunc() {
NativeModules.Toast.show('调用NativeToast成功');
}
render() {
return (
<SafeAreaView>
<StatusBar barStyle='dark-content' backgroundColor='#fff' />
<View style={
styles.container}>
<Text style={
{
color: '#000', fontSize: 30, fontWeight: 'bold' }} onPress={
() => this.toPageTwo()}>PageOne</Text>
<Text onPress={
() => this.testNativeFunc()} style={
{
backgroundColor:"#eee",padding:10}}>调用NativeToast</Text>
</View>
</SafeAreaView>
);
}
Note: Whenever the code in Native is changed, the application must be reinstalled to take effect: turn off the nodejs service, and re-execute npx yarn android!
Isn't it very simple?
How to call js locally? Here you need to use DeviceEventEmitter to emit events in local code and receive events in js code:
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
let eventEmitter;
componentDidMount = () => {
eventEmitter = DeviceEventEmitter.addListener('event', (params) => {
});
}
componentWillUnmount = () => {
if (eventEmitter) eventEmitter.remove();
}
Let's test it. When clicking the button to pop up Toast, let Native emit an event to js, and js receives the parameters and displays them:
Add sending code to ToastMoudle:
@ReactMethod
public void show(String msg) {
Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("event", "native调js");
}
Add the receiving code to PageOne:
import {
DeviceEventEmitter,
...
} from 'react-native';
let eventEmitter;
export default class PageOne extends React.Component {
constructor(props) {
super(props);
this.state = {
text: ""
};
}
...
componentDidMount = () => {
eventEmitter = DeviceEventEmitter.addListener('event', (params) => {
console.log("event>>" + params);
this.setState({
text: params
});
});
}
componentWillUnmount = () => {
if (eventEmitter) eventEmitter.remove();
}
render() {
return (
<SafeAreaView>
<StatusBar barStyle='dark-content' backgroundColor='#fff' />
<View style={
styles.container}>
<Text style={
{
color: '#000', fontSize: 30, fontWeight: 'bold' }} onPress={
() => this.toPageTwo()}>PageOne</Text>
<Text onPress={
() => this.testNativeFunc()} style={
{
backgroundColor: "#eee", padding: 10 }}>调用NativeToast</Text>
<Text style={
{
color: '#FF0000', fontSize: 20, marginTop: 20 }} >{
this.state.text}</Text>
</View>
</SafeAreaView>
);
}
}
To reinstall the app, click the button:
The call was successful!