Android RN和native 嵌套pop返回2层页面的实现
Android RN和native 嵌套pop返回2层页面的实现如题,现在有如下场景:页面A是RN的,跳转到页面B是native的,再从页面B跳转到页面C,C页面是RN的。即:RN -> Native -> RN在C页面执行了一些逻辑(如在酒店详情页选择了一个房型价格计划),现在需要直接返回到页面A,即需要把页面C、页面B都 finish掉,即pop两层。实现分析...
Android RN和native 嵌套pop返回2层页面的实现
如题,现在有如下场景:
页面A是RN的,跳转到页面B是native的,再从页面B跳转到页面C,C页面是RN的。
即: RN -> Native -> RN在C页面执行了一些逻辑(如在酒店详情页选择了一个房型价格计划),现在需要直接返回到页面A,即需要把页面C、页面B都 finish掉,即pop两层。
实现分析
因为RN页面特殊,不能直接通过finish两层的思路来实现。
原因: RN 依赖的activity TNReactNativeActivity,是Standard模式,在JS通过RNUtilModule调用Native的 popBackStack方法,通过ReactContextBaseJavaModule.java 中getCurrentActivity 获取activity,只能获取到当前依附的activity (页面C)(Get the activity to which this context is currently attached, or {@code null} if not attached),不能获取到Native 的activity(页面B)
public class RNUtilModule extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
RNUtilModule.java
/**
* 不安全的方法,仅提供给RN页面
* 用于RN页面,跳转到A-->B-->C-->D
* D点击按钮回到A页面,不点击时可返回到B,C页面,
* RNActivity暂时也无法设置为SingleTask
*
* @param request
* @param callback
*/
@ReactMethod
public void popBackStack(String request, Callback callback) {
LogUtils.i(TAG, "call native method : resolveUrl, request:{}", request);
final PopStackRequest popStackRequest = RNUtil.decodeFromJson(request, PopStackRequest.class);
if (getCurrentActivity() == null || popStackRequest == null) {
RNUtil.invokeErrorCallback(callback, RNConstant.ErrorCode.NOT_FOUND);
return;
}
mIndex = popStackRequest.popCount;
if (mIndex > 0 && getCurrentActivity() != null && !getCurrentActivity().isFinishing()) {
mIndex--;
getCurrentActivity().finish();
}
}
ReactContextBaseJavaModule.java
/**
* Get the activity to which this context is currently attached, or {@code null} if not attached.
*
* DO NOT HOLD LONG-LIVED REFERENCES TO THE OBJECT RETURNED BY THIS METHOD, AS THIS WILL CAUSE
* MEMORY LEAKS.
*
* For example, never store the value returned by this method in a member variable. Instead, call
* this method whenever you actually need the Activity and make sure to check for {@code null}.
*/
protected @Nullable final Activity getCurrentActivity() {
return mReactApplicationContext.getCurrentActivity();
}
finish两层的实现参考:
mIndex = popStackRequest.popCount;
if (mIndex > 0 && getCurrentActivity() != null && !getCurrentActivity().isFinishing()) {
mIndex--;
getCurrentActivity().finish();
}
实现思路
在页面C,调用返回并发送通知(页面C通知页面B自己销毁),返回到页面B,监听到页面C发来的销毁通知,页面B执行finish,销毁自己,这样就返回到页面A了。
代码参考
// pop两层,即回退2个页面
if (Platform.OS === 'android') {
bridge.emitNativeEventEmitter('TNReactNativeHotelListFinishNotification', {}); // 销毁酒店列表页
bridge.setLinkBack(null, function (d) {});
} else { // ios可直接pop两层
bridge.popBackStack({popCount:2},function (d) {
});
}
通过EventBus发送销毁通知:
@ReactMethod
public void emitEventRN(String request, final Callback callback) {
LogUtils.i(TAG, "call native method : emitEventRN, request:{}", request);
NotificationRequest notify = RNUtil.decodeFromJson(request, NotificationRequest.class);
if (notify == null) {
return;
}
EventBus.getDefault().post(notify);
}
页面B监听销毁通知、执行销毁逻辑:
B Activity
public void onEventMainThread(NotificationRequest event) {
if (event != null && HotelConstants.NotifName.FINISH_HOTEL_LIST.equals(event.notifName)) {
// 销毁当前页面
finish();
}
以上实现思路供参考,欢迎大家留意讨论~~
更多推荐


所有评论(0)