美文网首页
使用React-Navigation并且有多个ReactActi

使用React-Navigation并且有多个ReactActi

作者: 被虐的小鸡 | 来源:发表于2020-08-20 16:29 被阅读0次

    问题来源

    1.我们的项目中用到了React-Navigation来处理路由,其中用的又是StackNavigation。
    2.使用的是ActivityA横屏承载ReactNative的js页面,并且对Android的虚拟按键进行了统一处理
    3.最近突然有一个需求,需要再搞一个ActivityB承载一个单页面的竖屏视图

    问题暴露

    上面的需求实现起来很简单
    1.定义一个ActivityB

    public class ActivityB extends ReactActivity {
        @Override
        protected String getMainComponentName() {
            return "ActivityB";
        }
    
        @Override
        protected ReactActivityDelegate createReactActivityDelegate() {
            return new ReactActivityDelegate(this, getMainComponentName()) {
                @Override
                protected ReactRootView createRootView() {
                    //处理手势,也可以不用实现这个
                    return new RNGestureHandlerEnabledRootView(ActivityB.this);
                }
    
                @Nullable
                @Override
                protected Bundle getLaunchOptions() {
                    Intent intent = getIntent();
                    String flag="";
                    Bundle bundle = new Bundle();
                    if (intent.hasExtra("flag")){
                        flag = intent.getStringExtra("flag");
                        bundle.putString("flag",flag);
                    }
    
                    return bundle;
                }
            };
        }
    }
    
    

    2.在清单文件中声明

    <activity android:name=".ActivityB"
                android:screenOrientation="portrait"/>
    

    3.实现桥接方法让ReactNative调用,并且添加到package中,最终注册在Application中

    public IntentModule(@NonNull ReactApplicationContext reactContext) {
           super(reactContext);
    
           reactContext.addActivityEventListener(new ActivityEventListener() {
               @Override
               public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
                   if (requestCode==110&&resultCode==111){
                       if (data!=null){
                           WritableMap map = Arguments.createMap();
                           if (data.hasExtra("data")) {
                               String datas = data.getStringExtra("data");
                               map.putString("data",datas);
                           }
    
                           if (data.hasExtra("uri")) {
                               String uri = data.getStringExtra("uri");
                               map.putString("uri",uri);
                           }
                           reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                                   .emit("ActivityB", map);
                       }
                   }
               }
    
               @Override
               public void onNewIntent(Intent intent) {
    
               }
           });
       }
    
       @NonNull
       @Override
       public String getName() {
           return "IntentModule";
       }
    
    
       @ReactMethod
       public void jumpCameraActivityForResult(ReadableMap map){
           String flag = "";
          if (map.hasKey("flag")){
              flag = map.getString("flag");
          }
    
           Intent intent = new Intent(getCurrentActivity(), ActivityB.class);
    
          if (!TextUtils.isEmpty(flag)){
              intent.putExtra("flag",flag);
          }
    
          Objects.requireNonNull(getCurrentActivity()).startActivityForResult(intent,CAMERA_REQUEST_CODE);
       }
    
       @ReactMethod
       public void finish(ReadableMap map){
           String data="";
           if (map.hasKey("data")){
               data = map.getString("data");
           }
    
           String uri="";
           if (map.hasKey("uri")){
               uri=map.getString("uri");
           }
           Intent intent=new Intent();
           if (!TextUtils.isEmpty(data)) {
               intent.putExtra("data", data);
           }
           if (!TextUtils.isEmpty(uri)) {
               intent.putExtra("uri", uri);
           }
           Objects.requireNonNull(getCurrentActivity()).setResult(ACTIVITY_RESULT_CODE,intent);
           getCurrentActivity().finish();
       }
    

    4.直接在首页中点击进入的二级页面中加入跳转,并且点击返回
    最终会发现除了ActivityB返回了,二级页面也不在了。。。。。。。

    分析问题

    1.首先在跳转ActivityB之前我打印了路由栈中的所有路由
    2.在ActivityB退出之后我又打印了路由栈中的所有路由
    经过对比确实发现二级页面不见了(不在栈中了)

    3.我在路由的pop,rest等页面分别打了日志,发现并没有被调用
    排除了方法误调导致的问题

    4.去github的issuse里面去看看有没有别人遇到过这个问题
    5.百度(无果)
    查了一圈发现没有人提到这个问题(得嘞,还得自己排查)

    6.我后来就琢磨是不是把ActivityB的虚拟返回去掉,并且ActivityB显示全屏是不是可以解决这个问题
    尝试后发现果然可以。。。

    7.那没毛病,肯定是ReactNative的返回处理和原生的返回处理都被执行了,导致不仅ActivityB退出了,ReactNative中的二级页面也退出了
    8.去看看ReactActivity是如何处理返回的,果不其然发现优先处理ReactNative内部的返回

      @Override
      public void onBackPressed() {
        if (!mDelegate.onBackPressed()) {
          super.onBackPressed();
        }
      }
    

    到这里就简单了我不让他走ReactNative内部的返回不就行了,返回false给他


    到这里本次的问题就圆满解决了。
    附上ActivityB的整体源码

    public class ActivityB extends ReactActivity {
    
        @Override
        protected String getMainComponentName() {
            return "ActivityB";
        }
    
        @Override
        protected ReactActivityDelegate createReactActivityDelegate() {
            return new ReactActivityDelegate(this, getMainComponentName()) {
    
                @Override
                public boolean onBackPressed() {
                    return false;
                }
    
                @Nullable
                @Override
                protected Bundle getLaunchOptions() {
                    Intent intent = getIntent();
                    String flag="";
                    Bundle bundle = new Bundle();
                    if (intent.hasExtra("flag")){
                        flag = intent.getStringExtra("flag");
                        bundle.putString("flag",flag);
                    }
    
                    return bundle;
                }
            };
        }
    }
    

    相关文章

      网友评论

          本文标题:使用React-Navigation并且有多个ReactActi

          本文链接:https://www.haomeiwen.com/subject/gvtejktx.html