React Native 多入口在Android端和iOS端的差

作者: _海角_ | 来源:发表于2018-12-17 11:28 被阅读6次

    既然选择了多入口的方式,那么多入口和单入口的优劣势本文就不赘述了。
    iOS端
    ios端可以通过设置不同的端口号,加以区分不同的入口。

      NSURL *jsCodeLocation;
    #ifdef DEBUG
      //  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
    //设置不同的端口号
      jsCodeLocation = [NSURL URLWithString:@"http://192.168.1.177:8082/index.ios.bundle?platform=ios"];
      
    #else
    //  jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
      // 非DEBUG情况下启用热更新
      jsCodeLocation=[RCTHotUpdate bundleURL];
    #endif
      RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                          moduleName:@"MineAddressListView"
                                                   initialProperties:nil
                                                       launchOptions:nil];
      
      self.view = rootView;
    

    开发过程中 ,不同的端口号,起不同的服务 react-native start --port 8082,分别调试。

    Android 端
    Android 端 对于同一个App来讲,只有一个端口号。
    即通过如下方式修改:

    1. 打开调试工具(Dev Settings),可以通过(command+M) 完成;
    2. 点击 Debug server host & port for device,添加localhost:xxx其中xxx为新的端口地址;
    3. 重新reload一下,就可以从新的端口加载jsbundle了。

    修改了端口号,对于同一个app来讲,所有的RN入口都会使用同一个端口号。这个是和iOS端的最大区别。

    public class RNActivity extends ReactActivity {
        @Override
        protected String getMainComponentName() {
            return "MineAddressListView";
        }
    }
    

    这种方式针对RN端及其简单的时候(也即没有使用各种第三方,无需在启动中加载各种第三方package),是没有问题的。但是如果RN端相对复杂,虽然RNActivity本身没有使用第三方,但是RNActivity中引用的文件调用了第三方,上面这种方式都出出现第三方服务undefined is not an object,类似下面这种。


    image.png

    这时就需要使用和MainActivity中类似的方式加载了,

    public class MainActivity extends ReactActivity {
        private ReactRootView mReactRootView;
        private ReactInstanceManager mReactInstanceManager;
        private final int OVERLAY_PERMISSION_REQ_CODE = 1;  // 任写一个值
        @BindView(R.id.button)
        Button button;
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            StatusBarUtil.setStatusBar(this,false);
            mReactRootView = new ReactRootView(this);
            mReactInstanceManager = ReactInstanceManager.builder()
                    .setApplication(getApplication())
                    .setBundleAssetName("index.android.bundle")
                    .setJSMainModulePath("index.android")
                    .addPackage(new ReactContextBasePackage())
                    .addPackage(new MainReactPackage())
                    .addPackage(new WeChatPackage())
                    .setUseDeveloperSupport(BuildConfig.DEBUG)
                    .setInitialLifecycleState(LifecycleState.RESUMED)
                    .build();
    
            Bundle bundle = new Bundle();
            bundle.putBoolean("isNotFist", true);
            // 注意这里的MyReactNativeApp必须对应“index.js”中的
            // “AppRegistry.registerComponent()”的第一个参数
            mReactRootView.startReactApplication(mReactInstanceManager, "MineAddressListView", bundle);
            setContentView(mReactRootView);
        }
    }
    

    其实由上面也能看出来,多入口方式并不合适,至少对于Android端来讲,还是建议将入口统一。
    大概思考了一下,造成这种情况的原因是:
    .addPackage(new XXX())是在MainActivity 中加载的,而不是在MainApplication中加载的
    所以在新的入口RNActivity中,同样是需要 .addPackage(new XXX())

    至于为什么要在MainActivity中加载,这就引出来另一个问题了,官方文档倒是在MainApplication中加载,但是实际操作却不行,一直会报上面那种undefined is not an object错误。

    相关文章

      网友评论

        本文标题:React Native 多入口在Android端和iOS端的差

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