[JAVA] ReactNative Android Bridge Kommentar

Funktion

Native Modules Nehmen Sie als Beispiel das Modul, in dem ein Dialogfeld angezeigt wird.

[Funktion]

DialogModule.java


public class DialogModule extends ReactContextBaseJavaModule {
    //
    public DialogModule(@NonNull ReactApplicationContext reactContext) {
        super(reactContext);
    }
   //
   @Override
    public String getName() {
        return "DialogModule";
    }

    //
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        constants.put("SINGLE_BUTTON", "SINGLE");
        constants.put("DOUBLE_BUTTON", "DOUBLE");
        return constants;
    }

    //2, Wenn Sie auf die Schaltfläche "OK" im Dialogfeld klicken, wird "true" auf der Konsole angezeigt. (Ereignisbenachrichtigung) 3, Die aktuelle Uhrzeit wird angezeigt, wenn auf die Schaltfläche "DATUM" geklickt wird. (Rückruf-) Konstruktor So etwas wie ein Tag zum Aufrufen dieses Moduls Eine Funktion, die einen Dialog anzeigt, in dem Sie Klassenkonstanten definieren können, die in RN verwendet werden können
    @ReactMethod
    public void showDialog(String message, String type) {
        if (type.equals("SINGLE")) {
            new AlertDialog.Builder(getCurrentActivity())
                    .setTitle("DialogModule")
                    .setMessage(message)
                    .setPositiveButton("CLOSE", (dialog, which) -> {
                        dialog.dismiss();
                    })
                    .show();
        } else {
            new AlertDialog.Builder(getCurrentActivity())
                    .setTitle("DialogModule")
                    .setMessage(message)
                    .setPositiveButton("OK", (dialog, which) -> {
                        sendEvent();
                    })
                    .setNegativeButton("CLOSE", (dialog, which) -> {
                        dialog.dismiss();
                    })
                    .show();
        }
    }

    //Eine Funktion, die die aktuelle Uhrzeit anzeigt und zurückruft
    @ReactMethod
    private void getCurrentTime(Callback callback) {
        Calendar calendar = Calendar.getInstance();
        callback.invoke(calendar.getTime().toString());
    }

    //Ereignis, um zu benachrichtigen, dass auf die Schaltfläche geklickt wurde
    private void sendEvent() {
        WritableMap params = Arguments.createMap();
        params.putBoolean("click", true);
        getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("onClick", params);
    }
}

Kommentar

getName Sie müssen die Zeichenfolge schreiben, wenn Sie von RN wie "DialogModule" aufrufen.

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

getConstants Sie können Molue-Klassenkonstanten festlegen, die von RN aus verwendet werden können.

public Map<String, Object> getConstants() {
    final Map<String, Object> constants = new HashMap<>();
    constants.put("SINGLE_BUTTON", "SINGLE");
    constants.put("DOUBLE_BUTTON", "DOUBLE");
    return constants;
}

@ReactMethod Sie können die Methoden festlegen, die in RN verwendet werden können. Wenn Sie den Rückruf ausführen möchten, führen Sie ihn mit .invoke () aus.

@ReactMethod
private void getCurrentTime(Callback callback) {
    Calendar calendar = Calendar.getInstance();
    callback.invoke(calendar.getTime().toString());
}

Event (Listener) Sie können die Ereignisse festlegen, die in RN registriert werden können.

//Rückrufwert einstellen
WritableMap params = Arguments.createMap();
params.putBoolean("click", true);
//Legen Sie den Ereignisnamen und den Rückrufwert fest
getReactApplicationContext()
    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
    .emit("onClick", params);

Native UI Components Nehmen Sie eine Ansicht, in der ein Videoplayer als Beispiel angezeigt wird.

[Funktion] 1, Zeigen Sie den Videoplayer an. (Ansicht erstellen) 2, Empfange die URL von der RN-Seite mit Requisiten und spiele das Video ab. 3, Zeigen Sie das Protokoll am Ende der Wiedergabe an. (Ereignisbenachrichtigung anzeigen)

VideoViewManager.java


public class VideoViewManager extends SimpleViewManager<VideoView> {
    private Context context;

    //So etwas wie ein Tag, um dieses Modul aufzurufen
    @Override
    public String getName() {
        return "VideoView";
    }

    //So etwas wie ein Konstruktor, der einen Moment der zu verwendenden Ansicht zurückgibt
    @Override
    protected VideoView createViewInstance(ThemedReactContext reactContext) {
        this.context = reactContext;
        return new VideoView(reactContext);
    }

    //Eine Funktion, die mit dem von Props empfangenen Wert verarbeitet
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    @ReactProp(name="url")
    public void setVideoPath(VideoView videoView, String urlPath) {
        Uri uri = Uri.parse(urlPath);
        videoView.setMediaController(new MediaController(context));
        videoView.setVideoURI(uri);
        //Spielen Sie, sobald es spielbereit ist
        videoView.setOnPreparedListener(mp -> {
            videoView.start();
        });
        //Rufen Sie am Ende der Wiedergabe zu "onFinish" der Requisiten zurück.(Benachrichtigung)
        videoView.setOnCompletionListener(mp -> {
            ReactContext reactContext = (ReactContext)context;
            
            WritableMap event = Arguments.createMap();
            event.putString("message", "onDirectEvent");
            reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(videoView.getId(),"onDirectEvent",event);

            WritableMap event2 = Arguments.createMap();
            event2.putString("message", "onBubblingEvent");
            reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(videoView.getId(),"onBubblingEvent",event2);
        });
        videoView.getDuration();
    }

    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
                .put("onDirectEvent", MapBuilder.of("registrationName", "onDirectEvent"))
                .build();
    }

    @Override
    public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
                .put("onBubblingEvent", MapBuilder.of("phasedRegistrationNames",
                                    MapBuilder.of(
                                            "bubbled", "onBubble",
                                            "captured", "onCapture")))
                .build();
    }
}

Kommentar

getName Die Zeichenfolge beim Aufrufen von RN muss als "VideoView" beschrieben werden.

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

@ReactProp Setter-Methode, die Props of View empfängt Der Methodenname selbst kann beliebig sein @ReactProp (name =" Requisitenname ") public void setProp (Ansichtstypansicht, Wert vom Typ Requisiten)

@ReactProp(name="url")
public void setVideoPath(VideoView videoView, String urlPath) {
        // ...
}

createViewInstance Eine Funktion, die eine Instanz von View zurückgibt

@Override
protected VideoView createViewInstance(ThemedReactContext reactContext) {
    return new VideoView(reactContext);
}

Ereignisbenachrichtigung Sie können den Rückruf für Requisiten festlegen.

Veranstaltungsanmeldung

Es gibt zwei Methoden zum Registrieren von Ereignissen. ・ GetExportedCustomDirectEventTypeConstants ・ GetExportedCustomBubblingEventTypeConstants

getExportedCustomDirectEventTypeConstants Benachrichtigen Sie eine Requisite mit einem Ereignis. Wie man sich registriert MapBuilder.builder (). Put (" Ereignisname ", MapBuilder.of (" Registrierungsname "," Requisitenname ")). Build ();

getExportedCustomBubblingEventTypeConstants In einem Ereignis können zwei Requisiten benachrichtigt werden. Wie man sich registriert MapBuilder.builder (). Put (" Ereignisname ", MapBuilder.of (" phasedRegistrationNames ", MapBuilder.of (" gesprudelt "," Requisitenname 1 "," erfasst "," Requisitenname 2 ")). Build ();

//Funktion zum Registrieren eines Ereignisses 1
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
    return MapBuilder.<String, Object>builder()
            .put("onDirectEvent", MapBuilder.of("registrationName", "onDirectEvent"))
            .build();
}

//Funktion zum Registrieren eines Ereignisses 2
@Override
public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
    return MapBuilder.<String, Object>builder()
            .put("onBubblingEvent", MapBuilder.of("phasedRegistrationNames",
                                MapBuilder.of(
                                        "bubbled", "onBubble",
                                        "captured", "onCapture")))
            .build();
}

Rufen Sie "receiveEvent" an, wo Sie benachrichtigt werden möchten receiveEvent (" Ansichts-ID "," Ereignisname ", Rückrufwert)

// ...
ReactContext reactContext = (ReactContext)context;
//Prozess zur Benachrichtigung von Ereignis 1"onDirectEvent"Veranstaltung
WritableMap event = Arguments.createMap();
event.putString("message", "onDirectEvent");
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(videoView.getId(),"onDirectEvent",event);

//Prozess zur Benachrichtigung des Ereignisses 2"onBubblingEvent"Veranstaltung
WritableMap event2 = Arguments.createMap();
event2.putString("message", "onBubblingEvent");
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(videoView.getId(),"onBubblingEvent",event2);
// ...

Auf der RN-Seite wird das Ereignis wie folgt benachrichtigt

<VideoView
      onDirectEvent={({ nativeEvent }) => console.log(nativeEvent.message)} // onDirectEvent
      onCapture={({ nativeEvent }) => console.log(nativeEvent.message)} // onBubblingEvent
      onBubble={({ nativeEvent }) => console.log(nativeEvent.message)} // onBubblingEvent
/>

Registrierung der Modul- und UI-Komponente

Registrieren Sie das erstellte Modul und die UI-Komponente wie folgt

ExamplePackage.java


public class ExamplePackage implements ReactPackage {
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.<ViewManager>singletonList(
                //Mit zunehmenden UI-Komponenten hinzufügen
                new VideoViewManager()
        );
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext
            return Collections.<ViewManager>singletonList(
                //Fügen Sie weitere Module hinzu
                new DialogModule(reactContext)
        );
    }
}

Registrieren Sie das erstellte Paket in "getPackages" in MainApplication.java

MainApplication.java


@Override
protected List<ReactPackage> getPackages() {
      List<ReactPackage> packages = new PackageList(this).getPackages();
           //Fügen Sie hinzu, wenn die Anzahl der Pakete zunimmt
           packages.add(new ExamplePackage());
      return packages;
}

RN Seite Native Modules

Dialog.jsx


import React from 'react';
import { NativeModules } from 'react-native';
//Rückgabewert der Funktion getName("DialogModule")Angeben
DialogModule = NativeModules.DialogModule;

const Dialog = () => {
  const [date, setDate] = React.useState("");

  React.useEffect(() => {
    const eventEmitter = new NativeEventEmitter(DialogModule);
    eventEmitter.addListener('onClick', (event) => {
       console.log(event.change) // "true"
    });
  }, [])

  return (
    <>
      <TouchableOpacity onPress={() => DialogModule.showDialog('SINGLE BUTTON', DialogModule.SINGLE_BUTTON)}>
        <Text>SINGLE BUTTON Dialog</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={() => DialogModule.showDialog('DOUBLE BUTTON', DialogModule.DOUBLE_BUTTON)}>
        <Text>DOUBLE BUTTON Dialog</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={() => DialogModule.getCurrentTime(time => setDate(time))}>
        <Text>DATE</Text>
      </TouchableOpacity>
        <Text>CURRENT DATE:</Text>
      <Text>[ {date} ]</Text>
    </>
  )
}

export default Dialog

Native UI Components

VideoView.jsx


import React from 'react';
import { requireNativeComponent } from 'react-native';
VideoView = requireNativeComponent('VideoView');

const VideoView = () => {

  return (
    <>
      <VideoView 
        style={{ width: '100%', height: '100%' }}
        url="https://www.radiantmediaplayer.com/media/bbb-360p.mp4"
        onDirectEvent={({ nativeEvent }) => console.log(nativeEvent.message)}
        onCapture={({ nativeEvent }) => console.log(nativeEvent.message)}
        onBubble={({ nativeEvent }) => console.log(nativeEvent.message)} />
    </>
  )
}

export default VideoView

Bonus

Wenn Sie die in UI Component implementierte Funktion vom Modul aus aufrufen möchten

ExamplePackage.java


public class ExamplePackage implements ReactPackage {
    private ExampleViewManager instance;
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.<ViewManager>singletonList(
                instance
        );
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext
            instance = new ExampleViewManager();
            return Collections.<ViewManager>singletonList(
                //Übergeben Sie eine Instanz von ViewManager an das Modul
                //Danach können Sie die Methode der Instanz über die im Modul definierte Funktion aufrufen.
                new ExampleModule(reactContext, instance)
        );
    }
}

Schließlich

In Bezug auf den Bridge-Teil von Android hatte ich große Probleme mit nur englischen Artikeln und vielen Beispielcodes, die nicht funktionierten. Da ich nicht viel Zeit hatte, um einen Artikel zu schreiben, kann es zu Auslassungen oder Fehlern kommen. Verwenden Sie daher den Inhalt des Artikels als Referenz.

Als nächstes lautet der Artikel am 20. Tag des React Native Adventskalenders @ dukas "Talk about AB test": tada:

Recommended Posts

ReactNative Android Bridge Kommentar
Wie schreibe ich React Native Bridge ~ Android-Version ~
Verwenden Sie nativen Code unter Android
Verwenden der Native UI-Komponente mit React Native (Android-Version)
[Android] Hinweise zu XML
Aufbau einer Android-Umgebung, die selbst Affen verstehen können [React Native]
Verwenden Sie Java, das in Android Studio enthalten ist, um React Native zu erstellen
Passen Sie die Listenansicht auf Android an
Mehrteilige Übertragungsbibliothek auf Android
Verwenden Sie die serielle Kommunikation unter Android
ROS App Entwicklung auf Android