Cómo hacer amigos de React Native y código Java en Android

La necesidad de trabajar con la parte nativa de una aplicación React Native generalmente surge cuando un servicio no tiene una api especial para RN. Por lo tanto, un buen desarrollador debería poder al menos comprender cómo funciona la parte nativa de la aplicación. Este artículo proporcionará ejemplos de cómo una aplicación React Native interactúa con Android.



Módulo nativo



Primero, creemos una nueva clase en la carpeta android / app / src / main / java, la clase CustomModule:



package com.awesomeproject;
import android.widget.Toast;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.util.Map;
import java.util.HashMap;

public class CustomModule extends ReactContextBaseJavaModule {
    CustomModule (ReactApplicationContext context) {
        super(context);
        reactContext = context;
    }

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

    private static ReactApplicationContext context;
}


Esta clase contiene el método getName () requerido. Es por el nombre que devolverá este método que puede acceder al módulo nativo desde el código Javascript (más sobre esto más adelante).

Tenga en cuenta también que el constructor de la clase toma el contexto de la aplicación como argumento. El contexto de la aplicación es necesario cuando queremos interactuar con componentes de Android.



Creemos un método de la clase CustomModule que se llamará desde el código Javascript:



@ReactMethod
    public void show(String message, int duration) {
        Toast.makeText(context,"Hello world", Toast.LENGTH_LONG).show();
    }


Tenga en cuenta que para que el método esté disponible en RN, debe utilizar el decorador @ReactMethod.



La clase Toast es un componente de Android que puede activar el siguiente mensaje de brindis mediante el método show ().



Vincular el módulo con la aplicación de Android



Una vez creado el módulo, debe colocarse en un paquete ("paquete").



Creemos un paquete en el mismo espacio de nombres:



package com.awesomeproject;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;

import java.util.Collections;
import java.util.List;

public class CustomPackage implements ReactPackage {

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new CustomModule(reactContext));
        return modules;
    }

}


La interfaz "ReactPackage" contiene dos métodos obligatorios: "createNativeModules" y "createViewManagers". El administrador de vistas en código RN es un componente. Nuestro módulo utilizará funciones y no es un componente de la interfaz de usuario de Android y, por lo tanto, se coloca en el método "createNativeModules".



Nota: un paquete puede contener varios módulos.



A continuación, el paquete debe asociarse con la aplicación de Android de la siguiente manera:



    //MainApplication.java

@Override
    protected List<ReactPackage> getPackages() {
      @SuppressWarnings("UnnecessaryLocalVariable")
      List<ReactPackage> packages = new PackageList(this).getPackages();
      packages.add(new CustomPackage());
      return packages;
    }


Usando un módulo en código Javascript



Ahora intentemos llamar al método "show ()" en la aplicación RN:



const App = () => {
  NativeModules.ToastExample.show();
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}>
          <Text>text</Text>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};


Resultado:







Intercambio de datos entre aplicaciones RN y Android



Ahora, intercambiemos datos entre aplicaciones. Creemos dos nuevos métodos en la clase CustomModule para encontrar la suma:



      @ReactMethod
    public void sum(int a, int b, Promise res) {
        try {
            res.resolve(a+b);
        } catch (IllegalViewOperationException e) {
            res.resolve(e);
        }
    }


@ReactMethod
    public void sum(float a, float b, Callback success, Callback fail) {
        try {
            success.invoke((a+b));
        } catch (IllegalViewOperationException e) {
            fail.invoke(e.getMessage());
        }
    }


Las variables "a" y "b" vendrán del código Javascript y debe recordar acerca de la correspondencia de los tipos de datos entre Java y JS:







Nota: dado que el tipo Number corresponde a varios tipos de Java a la vez, usamos una sobrecarga creando dos métodos con el mismo nombre, pero diferentes tipos de parámetros.



Para devolver datos al código JS, el módulo com.facebook.react.bridge contiene los tipos Promise y CallBack.



Ahora usemos el método en Js:



const showRes = async () => {
const res = NativeModules.SendDataToRN.sum(400, 250);
   alert(res);
};

const App = () => {
   React.useEffect(() => {
	showRes();
   }, [])

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}>
          <Text>text</Text>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};


Resultado:







Conclusión



Los materiales del artículo se pueden utilizar en todas las situaciones en las que aún no se ha escrito la API para rn. Como puede ver en los ejemplos, el intercambio de datos entre aplicaciones es una operación bastante simple que no requiere un conocimiento profundo de la programación Java.



All Articles