# 将 NativeScript 插件迁移到 AndroidX
NativeScript 6.0 版本计划于 7 月发布,并随附对 AndroidX 的支持。我们还将放弃对 Android 支持库的支持,这是一项重大更改,意味着应迁移与其相关的代码。
该博客将提供您作为插件开发人员可以做的准备工作。
TIP
重要说明:NativeScript 6 项目将同时使用 useAndroidX 和 enableJetifier 启用。这意味着所有现有的库(.jar
以及.aar 您随附的或包含在插件中的文件)将jetifier
在构建时自动迁移。
也就是说,每个 NativeScript 插件都属于以下类别之一:
- 有没有需要迁移的插件。EY!
- 可以使插件与 support-lib 和 AndroidX 兼容。
- 有没有兼容性路径(或者它只是不值得)。您应该发布该插件的仅限 AndroidX 版本,以使其可用于 NativeScript 6.0。
让我们看看每种情况下推荐的前进方式。
# 无需迁移
示例:nativescript-localstorage
如果您的插件(及其依赖项)不以任何方式依赖于 Android 支持库-您就摆脱了困境。您现在可以停止阅读。
另外,如果插件使用依赖于 support-lib 的第三方本机库,但未在 JS / TS 代码中使用 support lib API,则很有可能您无需执行任何操作。Jetifier 将为您迁移库的构建时间。当然,如果不确定,最好总是进行测试。
# 版本控制
在这种情况下,无需发布新版本的插件。
# 使它与 Support-lib 和 AndroidX 兼容
示例:nativescript-permissions
在许多情况下,可以通过执行运行时检查来确定哪个插件可用,从而使您的插件与 support-lib 和 AndroidX 兼容。您可以查看 Nathanael Anderson 撰写的这个很棒的博客,了解如何做到这一点。他拥有(并维护)大量的高质量插件,因此您可以信任他。
在某些情况下,重新编写代码以使其兼容会花费更多的精力。主要是从支持库扩展类时。这是有关如何执行此操作的示例:
function useAndroidX {
return global.androidx && global.androidx.appcompat;
};
function getMyClass() {
if (useAndroidX()) {
// Class implementation using AndroidX
class MyCardView extends androidx.cardview.widget.CardView {
// implementation skipped for brevity
}
return MyCardView;
} else {
// Class implementation using support-lib
class MyCardView extends android.support.v7.widget.CardView {
// implementation skipped for brevity
}
return MyCardView;
}
}
// Get the final class
const MyCardViewClass = getMyClass();
# 什么?!但是,我有很多问题!
对!上面的代码看起来很奇怪。让我们尝试解决一些问题。
- 静态绑定生成器(SBG)如何知道生成绑定的两个实现中的哪一个?
SBG 将尝试为两者生成绑定。但是,只有在扩展构建时才知道的类的实现(在 Android 项目中引用了您的库)的实现中才能成功。因此,如果您要为 NativeScript 5 进行构建-它将在其上下文中具有 support-lib 并将设法生成一个扩展类android.support.v7.widget.CardView
,而不会为该扩展实现生成绑定androidx.cardview.widget.CardView
。为 NativeScript 6 进行构建时,情况恰恰相反。useAndroidX()
检查将确保您在运行时使用正确的实现。
TIP
重要提示: SBG 将extends
直接匹配该类。由于它实际上并不评估 JS 代码,因此不允许在其中放置动态代码。因此,以下操作将无效:
const supportLib = global.androidx ? androidx.cardview.widget : extends android.support.v7.widget;
class MyCardView extends supportLib.CardView { ... }
- 看起来有很多重复的代码?
您可以尝试通过在类的实现之外提取代码来共享一些代码。但是…是的,您的代码会变得不太漂亮。
- TypeScript 定义如何?
您可以使用的androidx
标签tns-platform-declarations
获取 AndroidX 的类 型(npm i tns-platform-declarations@androidx
)。它会为您提供 AndroidX 中类型的定义,但不会获得 support-lib 的定义。您可能要使用<any>
或“存根”其中一种口味(例如declare var androidx:any;
)
# 版本控制
迁移完成后,您可以安全地将这些更改发布为插件的次要版本或补丁版本。好消息是您现在可以执行此操作,并且插件在发布后将可与 NativeScript 6 一起使用。
# 没有兼容路径
示例:tns-core-modules
您的插件可能无法与 support-lib 和 AndroidX 兼容。这可能是由于多种原因造成的:
- Java 代码或第三方库依赖于 support-lib(由于某些原因,jetifier 无法处理)。
- 您正在 JS 代码中扩展 support-lib 类,并且您不想通过 androix 运行时检查膨胀代码。
- 您具有
android-manifest.xml
Jetifier 无法处理的支持 lib 配置或其他资源。
有一些工具可以帮助您进行迁移。您可以将 jetifier-standalone 工具用于本机依赖关系,和/或将 androidx-migration-tool 用于 JS / TS / Java 代码。您也可以在 NativeScript 中检查对 AndroidX 的支持,以获取有关迁移的提示。
# 版本控制
这是建议的行动计划:
- 迁移插件。
- 碰撞一个主要版本并将其发布
androidx
在 npm 的 tag 后面:$npm publish --tag androidx
- (发布 NativeScript 6.0 时)发布 AndroidX 版本。将 peerDependency 添加到中是一个好主意
"tns-core-modules": ">6.0.0"
。
TIP
注意:androidx 在正式的 NativeScript 6 发行版之前发布标签之后,将有机会给依赖此标签的其他插件和应用程序进行测试。
# 立即测试您的插件!
无论您的插件属于哪一类,强烈建议您现在使用androidx
android-runtime 和 tns-core-modules 的构建对其进行测试:
npm install tns-core-modules@androidx --save-exact
tns platform add android@androidx
npm install tns-platform-declarations@androidx --save-exact (if you need typings)
然后,您可以运行演示项目,以确保一切正常。