技术控

    今日:70| 主题:49369
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] React Native 整合指南

[复制链接]
萌面超人 发表于 2016-10-3 18:42:44
104 2

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
React-Native

  React-Native 目前是一个不错的多平台开发和快速开发的解决方案,它解决了很多开发上的痛点,并且作为 facebook 大厂出品,维护上有保障,因此学习 RN 是有好处的。当然,它目前还存在着很多的问题,但是都可以通过一些方案来规避和解决。RN 目前来说对 iOS 开发者比较友好,而 Android 开发环境则比较难以配置。
  HelloWorld

  学什么都得先来个 HelloWorld,RN 官方文档对 HelloWorld 已经讲的很详细了。
  1. > brew install node
  2. > brew install watchman
  3. > npm install -g react-native-cli
  4. > react-native init HelloWorld
复制代码
然后就自动创建了对应的 iOS 和 Android 工程,笔者自己使用的是 node4-lts 版本,watchman 用于监视文件是否改变,不过笔者记得以前版本 watchman 是通过 npm 安装的,并且不是强制要求。可能现在版本改动了,不装就不能运行。
  iOS

  1. {
  2.   "name": "HelloWorld",
  3.   "version": "0.0.1",
  4.   "private": true,
  5.   "scripts": {
  6.     "start": "node node_modules/react-native/local-cli/cli.js start"
  7.   },
  8.   "dependencies": {
  9.     "react": "15.3.2",
  10.     "react-native": "0.34.1"
  11.   }
  12. }
复制代码
这是 package.json 文件内容,里面依赖了 react 和 react-native。打开 iOS 工程,里面基本和普通的 iOS 工程差不多,Libraries 目录包括了 node_modules 文件夹下的依赖工程,    React.xcodeproj工程内含两段脚本,一个是    RCTJSCProfiler分析,一个是启动本地 node 服务器。AppDelegate.m 如下  
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3.   NSURL *jsCodeLocation;
  4.   jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
  5.   RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
  6.                                                       moduleName:@"HelloWorld"
  7.                                                initialProperties:nil
  8.                                                    launchOptions:launchOptions];
  9.   rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
  10.   self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  11.   UIViewController *rootViewController = [UIViewController new];
  12.   rootViewController.view = rootView;
  13.   self.window.rootViewController = rootViewController;
  14.   [self.window makeKeyAndVisible];
  15.   return YES;
  16. }
复制代码
主要的区别就是使用 RCTRootView 作为 RN 渲染视图添加到控制器上。并且指定了 bundleURL 和 moduleName,看过源码的应该知道,bundleURL 就是本地或者远程 jsbundle 路径,而 moduleName 就是 js 代码中注册的模块名,    jsBundleURLForBundleRoot:fallbackResource则是返回本地或者远程的 jsbundle 路径,这里就不细讲了,只要点开源码一看就懂。  
  Android

  Android 环境配置比 iOS 麻烦多了,因为 iOS URL 等配置都是明文放在 AppDelegate 代码中的,哪里创建了 RootView 都很清楚,而安卓就比较麻烦,    MainApplication实现了    ReactApplication接口,主要是生成了    mReactNativeHost成员变量。    mReactNativeHost持有    ReactInstanceManager类变量,初始化代码如下  
  1. ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
  2.       .setApplication(mApplication)
  3.       .setJSMainModuleName(getJSMainModuleName())
  4.       .setUseDeveloperSupport(getUseDeveloperSupport())
  5.       .setRedBoxHandler(getRedBoxHandler())
  6.       .setUIImplementationProvider(getUIImplementationProvider())
  7.       .setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
复制代码
这里可以看到指定了 jsMainModuleName 和是否显示开发者菜单的参数,再来看 MainActivity,它继承了 ReactActivity,只重写了一个方法
  1. /**
  2. * Returns the name of the main component registered from JavaScript.
  3. * This is used to schedule rendering of the component.
  4. */
  5. @Override
  6. protected String getMainComponentName() {
  7.     return "HelloWorld";
  8. }
复制代码
再来看它的父类 ReactActivity,里面有一个成员变量 ReactActivityDelegate,它接受两个参数初始化
  1. new ReactActivityDelegate(this, getMainComponentName());
复制代码
这就变相的将组件名传入了 mDelegate。再进入    ReactActivityDelegate,就能找到  
  1. private @Nullable ReactRootView mReactRootView;
复制代码
这就是 RootView,然后它的初始化如下
  1. protected void loadApp(String appKey) {
  2.     if (mReactRootView != null) {
  3.         throw new IllegalStateException("Cannot loadApp while app is already running.");
  4.     }
  5.     mReactRootView = createRootView();
  6.     mReactRootView.startReactApplication(
  7.       getReactNativeHost().getReactInstanceManager(),
  8.       appKey,
  9.       getLaunchOptions());
  10.     getPlainActivity().setContentView(mReactRootView);
  11. }
复制代码
这里的初始化实际上就是对应了 iOS 中 rootView 的初始化,只不过 Android 是 startReactApplication 而不是通过构造函数传递参数的方式。并且,主要的参数都是通过 ReactInstanceManager 来存储管理,appKey 实际上就是组件名,等同于 iOS 中的    moduleName,而    ReactInstanceManager初始化中的    setJSMainModuleName才是 jsbundle 名称。Android 甚至没有在代码中指定 remote server jsbundle 路径的地方,目前只能进入 app 然后打开    dev setting来修改远程服务器地址,当然,也可能是笔者没有找到,如果有找到的朋友请在评论中告诉我。而且    ReactInstanceManager初始化后面还有一小段代码  
  1. String jsBundleFile = getJSBundleFile();
  2. if (jsBundleFile != null) {
  3.     builder.setJSBundleFile(jsBundleFile);
  4. } else {
  5.     builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
  6. }
复制代码
发现了没,iOS 下远程 jsbundle 和本地 jsbundle 是通过一个方法统一处理的,而 Android 则需要两个参数维护。iOS 下 RN 只提供了 RootView,开发者只需要处理好 RootView 暴露的方法就行了,更加简单,而 Android 环境下则是提供了 ReactActivity 类来做封装,并且将参数拆成了好几个类,非常的麻烦。
  Integration With Existing Apps

  iOS

  手动 iOS 整合步骤如下:
  
       
  •       package.json
       
  •       创建带有 subspecs 的        Podfile用于引入所需要的第三方库,这需要 CocoaPods,虽然也可以手动 link 第三方库,但是目前笔者推荐使用 CocoaPods      
       
  •       index.ios.js
       
  •       RCTRootView
      
  当然,还有其他步骤,比如 ATS 的问题,不过一个合格的开发者应当都能完成,看上面这些步骤,你会发现实际上在 iOS 下,手动整合和 HelloWorld 基本是一致的。
  Android

  手动整合步骤如下
  
       
  •       package.json
       
  •       增加        com.facebook.react:react-native:+和        maven {}到 build.gradle      
       
  •       index.android.js
       
  •       ReactRootView
      
  是否发现了,在 Android 环境下,HelloWorld 工程和手动整合指南是不一样的,最主要的区别在于 HelloWorld 工程是继承 ReactActivity 来产生 Activity 的,而手动整合则是可以随便做,甚至可以在 Fragment 上面创建 RootView。
  总结

  就目前而言,RN 在 iOS 下无论是表现还是编码难度,都优于 Android 环境,Android 官方甚至没有一个很好的启动 App 方式,只能    react-native run-android。而且在性能方面,iOS 经过良好的编码和优化,是能够达到原生代码的水平的,而 Android 则有不少问题,但是 RN 虽然有这样那样的问题,它对整个跨平台开发是有很大贡献的,让开发者有机会多端开发,能涉足其他平台,而且相信未来这些问题都是能解决的。
友荐云推荐




上一篇:git图解:代码区域总结
下一篇:切图崽的自我修养-常用命令行操作
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

兰晓娟 发表于 2016-10-4 05:56:15
看了这么多帖子,第一次看到这么高质量内容!
回复 支持 反对

使用道具 举报

冯兵 发表于 2016-10-4 10:29:36
路过的帮顶
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表