“这个功能React Native实现不了,得用原生!” —— 当你听到这句话时别慌,React Native与Android的通信桥梁比你想象的更强大。本文将带你深入探索RN与Android原生的各种通信方式,让你轻松驾驭混合开发!
方式 | 方向 | 适用场景 | 性能 |
---|---|---|---|
原生模块 | Native→JS | 调用原生功能 | 中 |
原生组件 | JS→Native | 自定义UI组件 | 高 |
事件机制 | Native→JS | 原生事件通知 | 低 |
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);
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>
);
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();
}, []);
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));
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);
@ReactMethod(isBlockingSynchronousMethod = true)
public String syncMethod() {
// 同步方法(谨慎使用)
}
adb logcat | grep ReactNativeJS
console.log(NativeModules); // 查看所有原生模块
检查原生组件层级结构
public interface NativeBridge {
@ReactMethod
void invoke(String method, ReadableMap params, Promise promise);
}
private boolean verifyRequest(String token) {
// 实现安全验证逻辑
}
private void trackApiCall(String methodName) {
// 上报调用统计
}
记得第一次成功调通RN与原生通信时,那种突破次元壁的兴奋感至今难忘。当你在RN中调用原生相机API获得流畅体验,或者在原生代码中触发RN界面更新时,你会明白:真正的混合开发高手,能在JS和Native的世界自由穿梭。
当你把这些技术应用到实际项目中时,你会发现:React Native与原生通信不是限制,而是有无限可能
如果觉得写的不错,请动动手指点赞、关注、评论哦
如有疑问,可以评论区留言~