再见,Jetifier

移除Jetifier同时提升你的构建速度,只需6步。

Jetpack 套件能够帮助你更轻松的搭建高质量的APP,它包括了依赖库、工具和指导。它通过最佳实践、模板代码、以及简化复杂的任务来使得编码更轻松。让你更专注于你所关心的(业务)。

AndroidX是所有Jetpack库的包名,你可以把它理解成是开发、测试、发版和发布Jetpack库时用到的开源项目。

在2018年的I/O大会上,Google宣布Support库会以AndroidX重新命名,Support 28后不再更新,发布AndroidX 1.0。

Jetifier辅助迁移三方库到AndroidX。它通过修改依赖库的字节码来适配AndroidX的工程。

当你在项目中启动用Jetifier时(gradle.properties中android.enableJetifier = true),Gradle插件会在构建时将三方库里的Support转换成AndroidX,因此会对构建速度产生影响。因此,关闭Jetifier有助于加快构建速度。按照下面6个步骤执行,你可以将APP完全迁移到AndroidX,然后可以放心的去掉Jetifier了。

第1步

如果你的源码已经迁移到了AndroidX,你可以跳过这步,直接执行第2步。如果没有,请先完成源码的迁移工作。

第2步

梳理出项目里所有直接或间接依赖了Support的库。
你可以用Bye Bye JetifierGradle插件来做。
插件能梳理出符合下面特征的JAR或AAR:

  • 类里引入了Support库
  • layout里用到Support库
  • Manifest指向了Support库里的类
    当然,插件也能找出当前项目里对Support的引用。
我们为什么不用can-i-drop-jetifier插件呢?

can-i-drop-jetifier 插件只基于依赖关系图来检查support库,它还不足以让你移除Jetifier。有不少间接引用了Support的库,它们不会在POM文件体现。所以,如果你根据can-i-drop-jetifier 扫描结果,来移除Jetifier,你有可能会遇到运行时错误。相比之下,Bye Bye Jetifier通过检查JAR/AAR对Support的引用,找到更全的调用,帮助你避免运行时错误。

所以,这一步,你只需要在build.gradle中增加如下配置:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("com.dipien:bye-bye-jetifier:1.0.1")
    }
}
apply plugin: "com.dipien.byebyejetifier"

然后执行下面的命令:
./gradlew canISayByeByeJetifier -Pandroid.enableJetifier=false
如果你的项目里还有用到Support的地方,执行结果会失败,且打印出类似下面提示:

========================================
Project: app
========================================

Scanning com.github.bumptech.glide:glide:3.8.0
 * com/bumptech/glide/Glide.class -> android/support/v4/app/FragmentActivity
 * com/bumptech/glide/Glide.class -> android/support/v4/app/Fragment
 * com/bumptech/glide/manager/RequestManagerRetriever.class -> android/support/v4/app/FragmentManager
 * com/bumptech/glide/manager/RequestManagerRetriever.class -> android/support/v4/app/FragmentActivity
 * com/bumptech/glide/manager/RequestManagerRetriever.class -> android/support/v4/app/Fragment
 * com/bumptech/glide/manager/SupportRequestManagerFragment.class -> android/support/v4/app/Fragment

Legacy support dependencies:
 * com.android.support:support-annotations:28.0.0

> Task :canISayByeByeJetifier FAILED

第3步

通过前面两步,你发现了一些依赖了Support的SDK,现在你需要知道该如何移除它们对Support的引用。

第一选择是直接升级到最新的版本。幸运的话,最新版本的SDK已经适配了AndroidX。然而,如果SDK没适配,下面也有一些建议:

如果你是SDK源码的作者:

添加android.useAndroidX = true,迁移到AndroidX,然后升级所有的依赖,发布个新版本就可以了。

如果你不是SDK源码的所有者:
  1. 如果你没有源码,或对于你的项目来说,它太老了。你可以用jetifier-standalone命令行工具把AAR/JAR转成jetified之后的AAR/JAR。这个命令行的转换效果和你在代码里开启android.enableJetifier的效果是一样的。命令行如下:
    ./jetifier-standalone -i <source-library> -o <output-library>
    通过官方Jetifier文档,你能找到更多资料。
    你可以自定义groupId,把转换后的AAR/JAR,发布到任何Maven仓库里。然后把项目里的坐标指向成这个。
  2. 如果这个SDK代码是公有的,并且还有人维护,你可以把项目clone下来,自己迁移一下,提交PR给维护者。这种方式尽管有些费时,但如果你打算以后还用这个库的话,意义还是挺大的。
提示1

如果你想要用jetified转换后的版本替换的依赖关系是间接的,则你可以在Gradle中配置依赖替换规则,以便最终老的依赖会被替换为新的依赖。
举例来说,假设你有一个用了Support的SDK com.old:xxx:1.0.0,你把它迁移/转换成了 com.new:xxx:1.0.0。你可以通过如下配置来替换所有原始组件的用法:

// Replace artifacts with android support with the jetifier version
allprojects {
  configurations.all {
    resolutionStrategy.dependencySubstitution {
      substitute(module("com.old:xxx:1.0.0")).using(module("com.new:xxx:1.0.0")) 
    }
  }
}
提示2

如果你需要强制升级间接的依赖,你可以添加依赖约束
例如,com.sample:lib:1.0.0间接依赖了'''com.transitive:lib:1.0.0''',但后者用到了Support。你可以参照下面配置,强制使用后者的AndroidX版本:

api("com.sample:lib:1.0.0") 
constraints {
   implementation("com.transitive:lib:2.0.0") {
      because("previous versions use android support")
   }
}

第4步

你需要确认一下你的代码以及所有的依赖(含间接依赖)都没有Support了。
当你执行命令:

./gradlew canISayByeByeJetifier -Pandroid.enableJetifier=false

并且提示BUILD SUCCESSFUL,则意味着你移除了所有的Support依赖。

====================================================================
* No dependencies with legacy android support usages! You can say Bye Bye Jetifier. *
====================================================================
BUILD SUCCESSFUL in 15s
1 actionable task: 1 executed

现在,你可以移除gradle.properties里的android.enableJetifier了。

第5步

运行并测试你的APP,确保功能正常。

第6步

一旦你移除了Jetifier,为了避免无意中再引入含Support的依赖,你可以通过CI工具,在提交代码前执行canISayByeByeJetifier命令进行检查。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容