如何在Android上交朋友React Native和Java代码

当服务没有用于RN的特殊api时,通常需要使用React Native应用程序的本机部分。因此,优秀的开发人员应该至少能够理解应用程序本机部分的工作方式。本文将提供React Native应用程序如何与Android交互的示例。



本机模块



首先,让我们在android / app / src / main / java文件夹中创建一个新类,即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;
}


此类包含必需的getName()方法。通过此方法返回的名称,您可以从Javascript代码访问本机模块(稍后将进行介绍)。

还要注意,类构造函数将应用程序上下文作为参数。当我们想与Android组件交互时,需要应用程序上下文。



让我们创建CustomModule类的方法,该方法将从Javascript代码中调用:



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


请注意,为了使该方法在RN中可用,必须使用修饰符“ @ReactMethod”。



Toast类是一个Android组件,可以使用show()方法触发以下Toast消息。



将模块与Android应用程序链接



创建模块后,必须将其放入包装中(“包装”)。



让我们在相同的名称空间中创建一个包:



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;
    }

}


“ ReactPackage”接口包含两个必需的方法:“ createNativeModules”和“ createViewManagers”。RN代码中的视图管理器是一个组件。我们的模块将使用函数,而不是Android ui组件,因此位于“ createNativeModules”方法中。



注意:一个软件包可以包含多个模块。



接下来,该包必须与Android应用程序关联,如下所示:



    //MainApplication.java

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


在Javascript代码中使用模块



现在,让我们尝试在RN应用程序中调用“ show()”方法:



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


结果:







RN与Android应用之间的数据交换



现在,让我们在应用程序之间交换数据。让我们在CustomModule类中创建两个新方法来找到总和:



      @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());
        }
    }


变量“ a”和“ b”将来自Javascript代码,您需要记住Java和JS之间的数据类型的对应关系:







注意:由于Number类型一次对应于Java中的几种类型,因此我们通过创建两个具有相同名称但不同方法的方法来使用重载。参数类型。



要将数据返回到JS代码,com.facebook.react.bridge模块包含Promise和CallBack类型。



现在让我们使用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>
    </>
  );
};


结果:







结论



当尚未编写rn的api时,本文的材料可以在所有情况下使用。从示例中可以看到,应用程序之间的数据交换是一个相当简单的操作,不需要对Java编程有深入的了解。



All Articles