环境配置

使用android studio打开react native项目的android目录
在这里插入图片描述

在kotlin+java目录下添加代码

Native Module

安卓端开发Module

创建Module

package com.react_demo.custom;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;

@ReactModule(name="ColorModule") //ReactModule注解说明类作为Module使用
public class ColorModule extends ReactContextBaseJavaModule { //继承自父类ReactContextBaseJavaModule
    private ColorView view;

    public ColorModule(ReactApplicationContext reactContext) {
        super(reactContext);//重写构造函数,ReactApplicationContext上下文作为参数
    }

    @NonNull
    @Override
    public String getName() {
        return "ColorModule"; //Module的名称
    }

    public void setView(ColorView view){
        this.view=view;//设置View
    }

    @ReactMethod(isBlockingSynchronousMethod = false)//ReactMethod注解该方法作为Module的方法	
    public void setColor(int color){
		//操作View
        view.setColor(color);//修改背景颜色
        view.redraw();//触发重绘
    }
}

创建Package

将Module添加到Package

package com.react_demo.custom;

import androidx.annotation.NonNull;

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.Arrays;
import java.util.List;

public class ColorModulePackage  implements ReactPackage {//Package继承自ReactPackage
    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
        return Arrays.<NativeModule>asList(new ColorModule(reactContext)); //将Module添加到Package
    }
}

添加Package

添加到Package列表

//在MainApplication.kt文件中添加代码
class MainApplication : Application(), ReactApplication {

  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply {
              add(ColorModulePackage()) //添加Package到Package列表中,就加在这里,其他代码都是创建react native项目是自动生成的
            }

        override fun getJSMainModuleName(): String = "index"

        override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

        override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
        override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
      }

  override val reactHost: ReactHost
    get() = getDefaultReactHost(applicationContext, reactNativeHost)

  override fun onCreate() {
    super.onCreate()
    SoLoader.init(this, OpenSourceMergedSoMapping)
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      load()
    }
  }
}

react使用Module

import { NativeModules } from 'react-native';//导入NativeModules
const { ColorModule } = NativeModules;//导入创建的Module,名称与ReactModule注解的name一致
const changeColor = () => {
    ColorModule.setColor(4278255360);//使用Module中的方法
};

Native Component

安卓端开发Native Component

创建View

package com.react_demo.custom;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.ViewGroup;
import androidx.annotation.NonNull;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;

public class ColorView extends ViewGroup { //继承自ViewGroup类,这是一个android的类,不是react native的

    private String text;

    private int color= Color.RED;

    private Paint textPaint;

    private ColorModule colorModule;

    public void setText(String text){
        this.text=text;
    }

    public void setColor(int color){
        this.color=color;
    }

    public ColorView(Context context) {
        super(context);

        setWillNotDraw(false); // 启用 onDraw

        // 初始化 Paint 对象
        textPaint = new Paint();
        textPaint.setColor(Color.BLACK); 
        textPaint.setTextSize(50);     
        textPaint.setAntiAlias(true); 

        ReactContext reactContext = (ReactContext) getContext();//获取上下文ReactContext
        colorModule= reactContext.getNativeModule(ColorModule.class);//获取上下文中的Module
        colorModule.setView(this); //将View传递给Module,以便Module的方法可以操作View(这里我们会修改背景颜色,然后让View重绘)
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(color);//绘制背景颜色
        canvas.drawText(text,0,0,textPaint);
    }

    public void redraw(){
        postInvalidate();//触发重绘
    }
}

创建ViewManager

用来管理View

package com.react_demo.custom;

import androidx.annotation.NonNull;

import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;

public class ColorViewManager extends SimpleViewManager<ColorView> {//继承自SimpleViewManager
    @NonNull
    @Override
    public String getName() {
        return "ColorView"; //对应react端的组件名,react端使用<ColorView>来创建组件
    }

    @NonNull
    @Override
    protected ColorView createViewInstance(@NonNull ThemedReactContext context) {
		//重写createViewInstance,用来创建安卓端的View
        return new ColorView(context);
    }

    @ReactProp(name="text")//使用react端传递的参数,参数名为text,使用ReactProp注解
    public void setText(ColorView view,String text){ 
        view.setText(text);
    }
}

修改Package

添加ViewManager到Package

public class ColorModulePackage  implements ReactPackage {

	//...省略代码
	
    @NonNull
    @Override
    public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
        return Arrays.<ViewManager>asList(new ColorViewManager());//添加ViewManager到Package
    }
}


react端使用Component

导入安卓原生Component

文件名:ColorView.ts

import { requireNativeComponent, ViewProps } from 'react-native';

export interface ColorViewProps extends ViewProps {//View的属性接口,继承自ViewProps

  text?: string;//View的属性,需要与ViewManager中的ReactProp注解一一对应
}

const ColorView = requireNativeComponent<ColorViewProps>('ColorView');//导入原生Component,名称与ViewManager的getName方法返回的值一致
export default ColorView; //导出react Component

react使用

import ColorView from './ColorView'; // 引入原生组件
return (
        <View style={styles.container}>
          <ColorView text = "hello world"/>
		  <TouchableOpacity style={styles.button} onPress={changeColor}>
            <Text style={styles.buttonText}>修改颜色</Text>
          </TouchableOpacity> 
		</View>
	  )

EventEmitter

安卓端发送Event

Module发送Event

ColorModule.java中添加sendEvent方法

public class ColorModule extends ReactContextBaseJavaModule {
    void sendEvent(String eventName, @Nullable ReadableMap params) { //通知react端
        getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);//发送事件
    }
}

View重绘调用sendEvent

ColorView.java中在onDraw方法中添加代码

public class ColorView extends ViewGroup {
    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        //...省略代码
        WritableMap params = Arguments.createMap(); //创建Event参数
        params.putInt("color", color);

        colorModule.sendEvent("color_change", params); //调用Module的方法
    }
}

react端接收Event

import { NativeEventEmitter } from 'react-native';//导入NativeEventEmitter
  const { ColorModule } = NativeModules;
  const eventEmitter = new NativeEventEmitter(ColorModule);//创建Module对应的Emitter

  eventEmitter.addListener('color_change', (data) => {
    console.log('color change:', data.color);
  });//监听Module上的color_change事件

代码测试

  1. npx react-native start启动metro

  2. npx react-native run-android启动安卓程序
    在这里插入图片描述

  3. 在metro启动的终端按j打开DevTools启动调试

  4. 在 eventEmitter.addListener中下断点
    在这里插入图片描述

  5. 点击修改颜色按钮
    在这里插入图片描述

在这里插入图片描述

其他

Promise

安卓原生端

@ReactMethod
public void nativeOperationWithPromise(String input, Promise promise) {
    try {
        // 执行一些操作
        String result = "Processed: " + input;
        // 成功时调用resolve
        promise.resolve(result);
    } catch (Exception e) {
        // 失败时调用reject
        promise.reject("ERROR_CODE", e.getMessage());
    }
}

react端

import { NativeModules } from 'react-native';
const { MyNativeModule } = NativeModules;

async function callNativeWithPromise() {
  try {
    const result = await MyNativeModule.nativeOperationWithPromise('test');
    console.log('Result:', result);
  } catch (error) {
    console.error('Error:', error);
  }
}

Callback

安卓原生端

@ReactMethod
public void nativeOperationWithCallback(String input, Callback successCallback, Callback errorCallback) {
    try {
        String result = "Processed: " + input;
        successCallback.invoke(result);
    } catch (Exception e) {
        errorCallback.invoke(e.getMessage());
    }
}

react端

import { NativeModules } from 'react-native';
const { MyNativeModule } = NativeModules;

MyNativeModule.nativeOperationWithCallback(
  'test',
  (result) => {
    console.log('Success:', result);
  },
  (error) => {
    console.error('Error:', error);
  }
);
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐