Android native of React Native sends messages to js through deviceeventtwitter

Keywords: React Android Java Javascript

1 problem

Android sends messages to js natively and can carry data

 

 

 

2 implementation principle

Android native can use RCTEventEmitter to register events, then you need to specify the name of the event here, and then listen to the name of the same event on the js side, and you can receive the message and get the data

Key code for Android registration

reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);

The EventName here and the value of 'EventName' below need to be consistent

Monitoring on js

   componentWillMount(){  
      //Listen for an event named EventName
      DeviceEventEmitter.addListener('EventName', function() {  
          alert("Android send js msg success");  
      });                                
    }

 

 

 

3 code implementation

Please refer to some code and class files of my previous blogs

React Native implementation js calls Android native code

js of React Native calls Android native to use Callback to pass the result to js

Based on the above article, I added a Test.java class. The file is as follows. Here is the registration

package com.pro_react;


import android.content.Context;
import android.provider.Settings;
import android.support.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;


public class Test {

    //Define context object
    public ReactContext myContext;

    public Test(ReactContext context) {
        this.myContext = context;
    }

    //Define functions to send events
    public void sendEventToUi(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
    }

    public void sendMsg()
    {
        //Start the thread in this method, delay for 1 second, and then send the event to the JavaScript side.
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //Send an event named EventName
                WritableMap wm = Arguments.createMap();
                sendEventToUi(myContext,"EventName", wm);
            }
        }).start();
    }
}

Then it is added in the MyToastModule.java file. When js clicks the text to trigger the showMyName function, we will send a message to js. The MyToastModule.java file is as follows

package com.pro_react;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

/**
 * Created by chenyu on 9/15/18.
 */

public class MyToastModule extends ReactContextBaseJavaModule {

    public ReactContext mContext;
    public MyToastModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
    }

    /**
     * getName Method returns a string name, which is the module name in js
     * When we write js, we need to import this module. Here I use MyToast
     */
    @Override
    public String getName() {
        return "MyToast";
    }

    /**
     * This is the method called by js. You need to use the annotation @ react method. The return type must be void
     */
    @ReactMethod
    public void show() {
        Toast.makeText(getReactApplicationContext(), "I am chenyu", Toast.LENGTH_SHORT).show();
    }

    @ReactMethod(isBlockingSynchronousMethod = true)
    public String showMyName() {
        NotificationUtil util = NotificationUtil.getInstance(mContext);
        //util.showMessage();
        //Send message to ui
        new Test(mContext).sendMsg();
        return "chenyu1";
    }

}

The App.js file is modified as follows

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, NativeModules, DeviceEventEmitter} from 'react-native';

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});
var myAndroidToast = NativeModules.MyToast;
type Props = {};
export default class App extends Component<Props> {
   
   componentWillMount(){  
      //Listen for an event named EventName
      DeviceEventEmitter.addListener('EventName', function() {  
          alert("Android send js msg success");  
      });                                
    }

    constructor(props){
        super(props);
        this.state={
            myName:'chenzixuan',
        }
    }
  
  render() {
    return (
      <View style={styles.container}>
        <Text onPress={()=> this._androidShowMsg()} style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
        <Text style={styles.instructions}>{this.state.myName}</Text>
      </View>
    );
  }

    _androidShowMsg = () => {
       var value = myAndroidToast.showMyName();
       this.setState({myName:value});
        
    };
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

 

 

 

4 test results

App.js has been modified here, so you need to generate android.index.bundle file. Execute the command as follows

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

And then

react-native run-android

The effect is as follows

Click Welcome to React Native and the effect is as follows

Posted by timclaason on Sat, 28 Dec 2019 08:13:27 -0800