了解不同的运行时版本策略以及它们如何适合你的项目。
运行时版本是保证构建的原生代码和更新之间的兼容性的属性。当项目被制作成构建时,构建将包含一些无法通过更新更改的原生代码。因此,更新必须与构建的原生代码兼容才能在构建上运行。
¥Runtime versions are a property that guarantees compatibility between a build's native code and an update. When a project is made into a build, the build will contain some native code that cannot be changed with an update. Therefore, an update must be compatible with a build's native code to run on the build.
为了说明构建和更新如何交互,请看下图:
¥To illustrate how builds and updates interact, take a look at the following diagram:
构建可以被认为是两层:内置于应用二进制文件中的原生层和可与其他兼容更新交换的更新层。这种分离允许我们将错误修复发送到构建,只要错误修复的更新可以在构建内的原生层上运行。"runtimeVersion"
属性使我们能够保证更新与特定构建的原生代码兼容。
¥Builds can be thought of as two layers: a native layer that's built into the app's binary, and an update layer, that is swappable with other compatible updates. This separation allows us to ship bug fixes to builds as long as the update with the bug fix can run on the native layer inside the build. The "runtimeVersion"
property allows us to guarantee that an update is compatible with a specific build's native code.
由于更新必须与构建的原生代码兼容,因此每次更新原生代码时,我们都需要在发布更新之前进行新的构建。一些开发者仅在升级到新的 Expo SDK 时更新原生代码,而其他开发者可能会在构建之间或以其他时间间隔升级原生代码。以下是对可能适合你的项目的不同情况和配置的说明。
¥Since updates must be compatible with a build's native code, any time native code is updated, we're required to make a new build before publishing an update. Some developers only update native code when upgrading to a new Expo SDK, while others may upgrade native code between builds or at other intervals. Below is an explanation of different situations and configurations that may suite your project.
"runtimeVersion"
¥Setting "runtimeVersion"
为了在构建和更新之间更轻松地管理 "runtimeVersion"
属性,我们创建了从项目中已存在的另一条信息中派生运行时版本的策略。如果这些策略与项目的开发流程不匹配,还可以选择手动设置 "runtimeVersion"
。
¥To make managing the "runtimeVersion"
property easier between builds and updates, we've created policies that derive the runtime version from another piece of information already present in your project. If these policies do not match the development flow of a project, there's also an option to set the "runtimeVersion"
manually.
¥Runtime version policies
可用的策略记录在 expo-updates
库文档 中。
¥The available policies are documented in the expo-updates
library documentation.
¥Custom runtime version
你还可以设置满足 运行时版本格式要求 的自定义运行时版本:
¥You can also set a custom runtime version that meets the runtime version formatting requirements:
{
"expo": {
"runtimeVersion": "1.0.0"
}
}
对于想要手动管理运行时版本(与项目应用配置中存在的任何其他版本号分开)的开发者来说,此选项非常有用。它使开发者可以完全控制哪些更新与哪些版本兼容。
¥This option is good for developers who want to manage the runtime version manually, separately from any other version numbers present in a project's app config. It gives the developer complete control over which updates are compatible with which builds.
¥Platform-specific runtime version
你还可以为每个平台设置运行时版本,例如
¥You can also set runtime version per-platform, for example
{
"expo": {
"android": {
"runtimeVersion": "1.0.0"
}
}
}
或者:
¥Or:
{
"expo": {
"android": {
"runtimeVersion": {
"policy": "appVersion"
}
}
}
}
当同时设置顶层运行时和特定于平台的运行时时,特定于平台的运行时优先。
¥When both a top level runtime and a platform specific runtime are set, the platform specific one takes precedence.
¥Avoiding crashes with incompatible updates
发布更新时可能出现的主要问题是更新可能依赖于其运行的版本不支持的原生代码。例如,假设我们使用 "1.0.0"
的运行时版本进行了构建。然后,我们将该版本提交给应用商店并向公众发布。
¥The main issue that can arise when publishing updates is that the update could rely on native code that the build it's running on does not support. For instance, imagine we made a build with a runtime version of "1.0.0"
. Then, we submitted that build to the app stores and released it to the public.
后来,假设我们开发了一个依赖于新安装的原生库的更新,例如 expo-in-app-purchases
库,并且我们没有更新 "runtimeVersion"
属性,因此它仍然是 "1.0.0"
。如果我们发布更新,使用 "runtimeVersion"
或 "1.0.0"
的构建会认为具有相同运行时版本的传入更新是兼容的,并且会尝试加载更新。由于更新将调用构建中不存在的代码,因此应用将崩溃。
¥Later on, imagine that we developed an update that relied on a newly installed native library, like the expo-in-app-purchases
library, and we did not update the "runtimeVersion"
property, so that it is still "1.0.0"
. If we published an update, the builds with the "runtimeVersion"
of "1.0.0"
would think the incoming update with the same runtime version was compatible and it would attempt to load the update. Since the update would make calls to code that does not exist inside the build, the app would crash.
有几种方法可以避免此类崩溃:
¥There are a few ways to avoid crashes like this:
每当我们安装或更新原生代码时,都会迭代项目的应用配置 (app.json/app.config.js) 中的 "runtimeVersion"
属性。
¥Whenever we install or update native code, iterate the "runtimeVersion"
property in the project's app config (app.json/app.config.js).
创建应用的预览版本并将其加载到测试设备上。然后,将更新发布到 "preview" 分支,以确保其按预期工作,然后再将其发布到项目的生产分支。
¥Create a preview build of your app and load it on a test device. Then, publish the update to the "preview" branch to make sure it works as expected before publishing it to the project's production branch.
如果确实发生此错误,则你可以重新发布以前的已知良好更新,然后要求用户删除该应用并重新安装。
¥If this error does occur, then you can republish a previous known-good update, then ask users to delete the app and reinstall it.
将来,expo-updates
库将防止许多此类实例导致应用崩溃。如果我们能够检测到这个特定问题,我们将自动回滚到以前的更新,而不是加载错误的更新。
¥In the future, the expo-updates
library will prevent many instances of this from crashing the app. If we can detect this particular issue, we'll automatically roll back to a previous update instead of loading the bad update.