ReactNative开发还不会跟android交互通信吗?赶快看一下这篇文章,瞬间豁然开朗-原来跨平台调用原生方法竟然如此简单
reactnative和android进行交互通信,让不会原生的你,可以很快掌握应用原生实现rn实现不了的功能
·
React Native 与 Android 原生通信全攻略
“这个功能React Native实现不了,得用原生!” —— 当你听到这句话时别慌,React Native与Android的通信桥梁比你想象的更强大。本文将带你深入探索RN与Android原生的各种通信方式,让你轻松驾驭混合开发!
一、通信原理总览
1.1 React Native架构简析
- JS层:运行JavaScript代码
- Native层:运行原生Java/Kotlin代码
- Bridge:负责双向通信的异步通道
1.2 三种核心通信方式
| 方式 | 方向 | 适用场景 | 性能 |
|---|---|---|---|
| 原生模块 | Native→JS | 调用原生功能 | 中 |
| 原生组件 | JS→Native | 自定义UI组件 | 高 |
| 事件机制 | Native→JS | 原生事件通知 | 低 |
二、创建原生模块(Native→JS)
2.1 基础模块创建步骤
1. 创建原生模块类:
// ToastModule.java
public class ToastModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "ToastExample"; // JS中引用的名称
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(reactContext, message, duration).show();
}
}
2. 创建Package类:
public class CustomToastPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ToastModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
3. 注册Package:
// MainApplication.java
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CustomToastPackage() // 添加自定义包
);
}
4. JS端调用:
import { NativeModules } from 'react-native';
const { ToastExample } = NativeModules;
ToastExample.show('Hello from Native!', ToastExample.LONG);
三、创建原生UI组件(JS→Native)
3.1 自定义View组件
1. 创建ViewManager:
public class CustomViewManager extends SimpleViewManager<TextView> {
@Override
public String getName() {
return "CustomNativeView";
}
@Override
protected TextView createViewInstance(ThemedReactContext context) {
TextView textView = new TextView(context);
textView.setText("This is native TextView");
return textView;
}
@ReactProp(name="text")
public void setText(TextView view, String text) {
view.setText(text);
}
}
2. 注册到Package:
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new CustomViewManager()
);
}
3. JS端使用:
import { requireNativeComponent } from 'react-native';
const CustomNativeView = requireNativeComponent('CustomNativeView');
const App = () => (
<View style={{flex: 1}}>
<CustomNativeView
text="Hello from JS!"
style={{width: 200, height: 100}}
/>
</View>
);
四、事件通信(Native→JS)
4.1 发送事件到JS
1. 原生端发送事件:
// 在原生模块中添加方法
private void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
// 调用示例
WritableMap params = Arguments.createMap();
params.putString("message", "Native Event!");
sendEvent(reactContext, "onCustomEvent", params);
2. JS端监听事件:
import { DeviceEventEmitter } from 'react-native';
useEffect(() => {
const subscription = DeviceEventEmitter.addListener(
'onCustomEvent',
(event) => console.log(event.message)
);
return () => subscription.remove();
}, []);
五、高级通信技巧
5.1 Promise异步回调
1. 原生模块实现:
@ReactMethod
public void asyncTask(String input, Promise promise) {
try {
String result = doComplexWork(input);
promise.resolve(result);
} catch (Exception e) {
promise.reject("ERROR_CODE", e.getMessage());
}
}
2. JS端调用:
ToastExample.asyncTask('input')
.then(result => console.log(result))
.catch(error => console.error(error));
5.2 直接调用常量
1. 暴露常量:
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put("SHORT", Toast.LENGTH_SHORT);
constants.put("LONG", Toast.LENGTH_LONG);
return constants;
}
2. JS端使用:
ToastExample.show('Hello', ToastExample.LONG);
六、性能优化策略
6.1 减少跨桥通信
- 批量传输数据
- 避免高频次通信
- 对大文件使用原生路径而非base64
6.2 线程优化
@ReactMethod(isBlockingSynchronousMethod = true)
public String syncMethod() {
// 同步方法(谨慎使用)
}
6.3 内存管理
- 及时移除事件监听
- 避免在原生端持有JS引用
七、调试技巧
7.1 检查模块注册
adb logcat | grep ReactNativeJS
7.2 Chrome调试
console.log(NativeModules); // 查看所有原生模块
7.3 React DevTools
检查原生组件层级结构
八、企业级实践方案
8.1 统一通信协议
public interface NativeBridge {
@ReactMethod
void invoke(String method, ReadableMap params, Promise promise);
}
8.2 安全校验
private boolean verifyRequest(String token) {
// 实现安全验证逻辑
}
8.3 监控统计
private void trackApiCall(String methodName) {
// 上报调用统计
}
总结:跨平台打破平台边界
记得第一次成功调通RN与原生通信时,那种突破次元壁的兴奋感至今难忘。当你在RN中调用原生相机API获得流畅体验,或者在原生代码中触发RN界面更新时,你会明白:真正的混合开发高手,能在JS和Native的世界自由穿梭。
当你把这些技术应用到实际项目中时,你会发现:React Native与原生通信不是限制,而是有无限可能
如果觉得写的不错,请动动手指点赞、关注、评论哦
如有疑问,可以评论区留言~
更多推荐

所有评论(0)