React Native实践React Native开发React Native开发经验集

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

2018-12-17  本文已影响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错误。

上一篇下一篇

猜你喜欢

热点阅读