前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版

React Native 适配 Android 与 iOS 完整总结篇

首页2019-06-08 14:50:12Front-End
RNReact移动端

同一份 React Native 代码,在 iPhone 模拟器上跑得好好的,装到 Android 真机上导航栏就顶进状态栏,react-native-vector-icons 的图标全变成豆腐块,打包出来的 APK 还死活装不上。做 RN 双端适配那阵子,这类问题基本每周都要撞一遍。这篇是我当时攒下来的完整笔记,从 macOS 上把 iOS 和 Android 两套环境搭起来开始,一路记到矢量图标接入、两套路由方案怎么选、Flexbox 在 RN 里和 Web 的差异、Platform.OS 分支怎么写,最后落到 Android 签名打包。读完你能拿到一份可以直接照着抄的双端适配清单。

在本篇文章中,我们将从浅入深,和大家一起学习以下知识:

  • iOS 与 Android 双端开发环境怎么搭,react-native init 卡人的那几个点在哪
  • 远程调试、Live Reload、genymotion 模拟器和安卓真机调试的完整链路
  • react-native-vector-icons 在两个平台上的自动配置与手动配置
  • react-native-router-flux 的用法和全套 API 速查表
  • RN 常见组件、样式写法、长列表与网络请求的注意事项
  • RN 里的 Flexbox 和 Web CSS 到底差在哪几处
  • Platform.OS、api doc 平台标识、图片 @2x/@3x 这些具体的适配手段
  • react-navigation 的页面跳转、参数传递与标题栏定制
  • Android 签名打包 APK 的完整步骤
  • 这套 2019 年的写法,放到今天的 RN 新架构下哪些还成立、哪些已经变了

先说清楚一件事。这篇笔记写于 2019 年 6 月,当时 React Native 还是老架构,JS 和原生之间靠 Bridge 异步通信,iOS 上默认跑 JavaScriptCore。后来官方推了新架构,渲染层换成 Fabric,原生模块换成 TurboModules,默认引擎换成 Hermes,react-native link 这套手动 link 流程也被自动 linking 取代了。文中的命令和配置我一个字都没删,它们记录了那个版本真实的样子;每一节后面我会另起一段,补上现在的做法和已经废弃的部分。具体版本号和 API 名字请以 官方文档为准,我不打算凭记忆瞎写。

# 一、环境搭建

RN 劝退新人的第一关从来不是写代码,是环境。iOS 和 Android 两套原生工具链要各配一遍,任何一环缺了都是编译到一半报一串看不懂的原生错误。这一节把两边的步骤拆开走一遍,顺带把调试链路也串上,因为环境搭完不会调试,等于白搭。

# 1.1 React Native环境搭建

# 1.1.1 IOS环境搭建

环境:MacOS

iOS 这边只能在 macOS 上做,这是 Xcode 的硬限制,Windows 用户从一开始就只能搞 Android。先把 Node 和 Watchman 装上,前者跑打包器,后者是 Facebook 出的文件系统监听工具,RN 的 Metro 打包器靠它感知文件变化,装了之后热更新明显跟手。

# 如果你已经安装了 Node,请检查其版本是否在 v8.3 以上
brew install node 

# Watchman则是由 Facebook 提供的监视文件系统变更的工具。安装此工具可以提高开发时的性能
brew install watchman
@前端进阶之旅: 代码已经复制到剪贴板
  • 注意:不要使用 cnpm!cnpm 安装的模块路径比较奇怪,packager 不能正常识别!

这条注意事项要单独拎出来说。cnpm 为了处理依赖会把 node_modules 铺成一堆软链接结构,Metro 顺着这些链接找模块的时候会解析到奇怪的路径上,报出来的错通常是「找不到某个模块」,但你去目录里看模块明明在。这个我踩过,排查了小半天才反应过来是包管理器的锅。要装源慢就配 registry 镜像,别换客户端。

npm install -g yarn react-native-cli
@前端进阶之旅: 代码已经复制到剪贴板

1. 创建新项目

init 命令默认会创建最新的版本,而目前最新的0.45 及以上版本需要下载 boost 等几个第三方库编译。这些库在国内即便翻墙也很难下载成功,导致很多人无法运行iOS项目。可以暂时创建0.44.3的版本

react-native init MyApp --version 0.44.3
@前端进阶之旅: 代码已经复制到剪贴板

这里锁 0.44.3 是个很有年代感的操作。0.45 之后 iOS 端编译需要从源码拉 boost、folly、glog 这几个 C++ 依赖,下载源在国内经常连不上,编译走到一半就断在下载环节。当时的通用解法就是退版本,或者手动把这几个压缩包塞进 ~/.rncache 目录再重编。

现在这条建议已经不适用了。新版本的依赖分发方式变了,iOS 侧依赖统一走 CocoaPods 管理,而且 react-native-cli 这个全局包官方早就不推荐装,改用 npx react-native@latest init(更晚的版本又推荐走 Community CLI,具体以官方文档为准)。如果你是现在才开始新项目,直接按官网的最新指引走,不要锁 0.44.3,那个版本连 Hooks 都还没有。

2. 编译并运行 React Native 应用

1). 运行方式一 在你的项目目录中运行react-native run-ios

cd MyApp
react-native run-ios
@前端进阶之旅: 代码已经复制到剪贴板

2). 运行方式二 在xCode中运行

打开xcode选择项目中myApp/ios/myApp.xcodeproj,然后点击左上角运行即可

更多详情 https://reactnative.cn/docs/getting-started.html

两种跑法的差别在于,命令行方式会顺带帮你起 Metro 打包服务,适合日常改 JS;Xcode 方式能看到完整的原生编译日志,一旦是原生层报错,只有这条路能定位。我的习惯是平时用命令行,编译一失败就切回 Xcode 看红字。

3. 远程调试

  • ctrl + R刷新
  • ctrl + D 选择对应的工具调试

模拟器上按 Command + D(文中写的 ctrl + D 是 Windows/Linux 键位习惯,macOS 模拟器上是 Command + D)会弹出开发者菜单,里面的刷新、远程调试、性能监控都在这。真机上则是摇一摇手机弹出同一个菜单。

RN 开发者菜单,包含 Reload 与 Debug 选项

Enable Live Reload

当你的js代码发生变化后,React Native会自动生成bundle然后传输到模拟器或手机上

Live Reload 和后面会提到的 Hot Reloading 不是一回事。Live Reload 是整个应用重新加载,页面状态全丢;Hot Reloading 只替换改动的模块,尽量保住当前页面的 state。改样式的时候用 Hot Reloading 效率高得多,改路由结构或者顶层逻辑就老老实实整刷。

Live Reload 开启后代码保存即刷新的效果

在浏览器中打开 http://localhost:8081/debugger-ui

远程调试的原理是把 JS 代码丢到 Chrome 的 V8 里跑,再通过 WebSocket 把结果发回设备。这就带来一个当年很典型的坑,开了远程调试之后所有涉及原生同步调用的东西行为都会变,性能数据也完全不能参考。所以调逻辑可以开,测性能必须关。关于双端性能怎么量,我另外整理过一篇 React Native iOS/Android 真机性能剖析,那里讲得更细。

Chrome debugger-ui 页面

巧用Sources面板

远程调试打开后,Chrome DevTools 的 Sources 面板能直接给 RN 的 JS 打断点,和调网页没什么区别。断点、条件断点、调用栈、作用域变量都在,比一路 console.log 舒服。

Chrome DevTools Sources 面板断点调试 RN 代码

这里也补一句现状。基于 Chrome debugger-ui 的远程调试方案在后来的版本里被逐步淘汰了,官方转向了 Hermes 引擎自带的调试协议和内置的 DevTools,调试时 JS 就在设备上跑,不再搬到浏览器里,前面说的「开了远程调试行为会变」这个坑因此也就不存在了。新项目按官方文档的调试章节走即可。

指定模拟的设备类型

  • 你可以使用--simulator参数,在其后加上要使用的设备名称来指定要模拟的设备类型(目前默认为"iPhone X")。如果你要模拟 iPhone 4s,那么这样运行命令即可:react-native run-ios --simulator "iPhone 4s"。
  • 你可以在终端中运行xcrun simctl list devices来查看具体可用的设备名称

指定设备这件事在做适配的时候用得非常频繁。刘海屏和非刘海屏的安全区表现不一样,小屏机上布局容易挤,所以最少要在一台带刘海的和一台小屏机上各过一遍。xcrun simctl list devices 列出来的名字必须一字不差地传给 --simulator,多个空格都不行。

xcrun simctl list devices 输出的可用模拟器列表

# 1.1.2 安卓环境搭建

Android 这边比 iOS 麻烦,因为要多配一套 JDK 和 Android SDK,还要手动设环境变量。整个流程的核心就四件事,装 JDK、装 Android Studio、在 SDK Manager 里勾对版本、把 ANDROID_HOME 写进 shell 配置。顺序不能乱,SDK 没装完就去配环境变量,react-native run-android 只会告诉你找不到 SDK。

安装依赖

必须安装的依赖有:Node、Watchman 和 React Native 命令行工具以及 JDK 和 Android Studio

brew install node
brew install watchman
@前端进阶之旅: 代码已经复制到剪贴板
npm install -g yarn react-native-cli
@前端进阶之旅: 代码已经复制到剪贴板

Java Development Kit

React Native 需要 Java Development Kit [JDK] 1.8(暂不支持 1.9 及更高版本)。你可以在命令行中输入

  • javac -version来查看你当前安装的 JDK 版本。如果版本不合要求,则可以到 官网上下载

JDK 版本这块当年是个高频踩坑点。机器上装了 JDK 9 或更高版本,Gradle 编译会直接报一堆和 javax.xml.bind 相关的错,看起来毫无头绪,实际就是版本不对。当时的标准答案就是老老实实退回 1.8。

这条现在已经过期了。RN 后续版本对 JDK 的要求一路上调,社区版本目前普遍要求 JDK 17 及以上,具体哪个 RN 版本对应哪个 JDK 请查官方的 Environment setup 页面,别照着这篇 2019 年的笔记去装 1.8。

1. 安装 Android Studio

首先下载和安装 Android Studio,国内用户可能无法打开官方链接,请自行使用搜索引擎搜索可用的下载链接。安装界面中选择"Custom"选项,确保选中了以下几项

  • Android SDK
  • Android SDK Platform
  • Performance (Intel ® HAXM)
  • Android Virtual Device

然后点击"Next"来安装选中的组件。安装完成后,看到欢迎界面时,就可以进行下面的操作了

2. 安装 Android SDK

Android Studio 默认会安装最新版本的 Android SDK。目前编译 React Native 应用需要的是Android 8.1 (Oreo)版本的 SDK。你可以在 Android Studio 的 SDK Manager 中选择安装各版本的 SDK

fe
  • 一、环境搭建
    • 1.1 React Native环境搭建
      • 1.1.1 IOS环境搭建
      • 1.1.2 安卓环境搭建
    • 1.2 安卓设备真机调试
    • 1.3 移除vscode装饰器报错
  • 二、矢量图标的运用
    • 2.1 android平台
    • 2.2 IOS平台
  • 三、react-native-router-flux的使用
    • 3.1 简介
    • 3.2 简单例子
    • 3.3 react-native-router-flux之API
      • 3.3.1 Router
      • 3.3.2 Scene
      • 3.3.3 Tabs ( or )
      • 3.3.4 Stack ()
      • 3.3.5 Tab Scene (child within Tabs)
      • 3.3.6 Drawer ( or )
      • 3.3.7 Modals ( or )
      • 3.3.8 Lightbox ()
      • 3.3.9 Actions
      • 3.3.10 ActionConst
      • 3.3.11 Universal and Deep Linking
  • 四、React Native基础知识
    • 4.1 常见组件
    • 4.2 样式
    • 4.3 高度与宽度
    • 4.4 处理文本输入
    • 4.5 如何使用滚动视图
    • 4.6 如何使用长列表
    • 4.7 网络
  • 五、React Native布局
    • 5.1 宽和高
    • 5.2 和web中的差异
    • 5.3 Layout
      • 5.3.1 容器属性
      • 5.3.2 横轴和竖轴
      • 5.3.3 flexDirection
      • 5.3.4 flexWrap
      • 5.3.5 justifyContent
      • 5.3.6 alignItems
      • 5.3.7 alignSelf
      • 5.3.8 flex
    • 5.4 视图边框
    • 5.5 尺寸
    • 5.6 外边距
    • 5.7 内边距
    • 5.8 边缘
    • 5.9 定位(position)
  • 六、React Native适配
    • 6.1 Platform.OS
    • 6.2 留意api doc的android或ios标识
    • 6.3 组件选择
    • 6.4 图片适配
  • 七、react-navigation
    • 7.1 页面切换
    • 7.2 传递参数给路由
    • 7.3 配置标题栏
      • 7.3.1 动态设置标题
      • 7.3.2 使用setParams更新navigationOptions
      • 7.3.3 调整标题样式
      • 7.3.4 统一配置所有页面头部defaultNavigationOptions
      • 7.3.5 覆盖共享的navigationOptions
    • 7.4 标题栏和其所属的页面之间的交互
  • 八、打包
    • 8.1 修改app名称、logo、启动图
    • 8.2 Android打包APK
    • 8.3 IOS打包
  • 九、更多参考
  • 总结
  • 参考

← Taro跨平台开发实践 多端编译原理与踩坑总结Vue API 盲点解析 performance errorHandler nextTick 与 watch →