先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
Android官方提供了具体的迁移指引。具体参见文档:
developer.android.com/jetpack/and…
Just Start!
以下主要记录实际项目中的迁移过程,以及遇到的问题及解决。
Refactor > Migrate to AndroidX
操作后,AS会有对应的迁移提醒,提示你去备份项目文件,如有必要可以先备份。但一般而言,AS项目都是基于Git进行管理,直接单独切一个分支进行迁移操作即可,此处备份成zip现实意义不大。
点击Migrate
后,会出现弹窗Looking for Usages
,开始在当前项目中搜索所有可能需要迁移的源文件,包括代码源文件、XML文件、build.gradle配置文件等,最终会列出当前主工程使用到支持库的所有文件列表。
点击Do Refactor
确认迁移,AS自动执行迁移AndroidX的替换过程。如将对应的支持库类名、包名、构件名等都替换成相应的AndroidX形式。
一点时间后,主工程替换完成。此时打开gradle.properties
,会发现自动添加了如下配置项。
android.useAndroidX=true
android.enableJetifier=true
android.useAndroidX=true
,表示主工程使用AndroidX形式。
android.enableJetifier=true
,表示针对主工程中使用到的三方库,也会自动执行AndroidX的替换过程。
同时,在自动执行三方库的替换时,出下了如下报错信息:
ERROR: Unable to resolve dependency for ‘:MyCorn@prodDebug/compileClasspath’: Failed to transform file ‘fingerprint-1.1.1.aar’ to match attributes {artifactType=processed-aar} using transform JetifyTransform
大致的意思是使用JetifyTransform
对fingerprint-1.1.1.aar
进行替换过程中,出现了问题。但具体问题没有进一步的提示信息。于是,直接通过命令执行下构建看一下:
./gradlew assembleDevDebug
…
…
1: Task failed with an exception.
- What went wrong:
Could not resolve all files for configuration ‘:MyCorn:devDebugCompileClasspath’.
Failed to transform file ‘fingerprint-1.1.1.aar’ to match attributes {artifactType=processed-aar} using transform JetifyTransform
Failed to transform ‘/Users/corn/.gradle/caches/modules-2/files-2.1/com.corn.feature/fingerprint/1.1.1/ae2da4c824fb2923eac7a1340222d50d6308f7ea/fingerprint-1.1.1.aar’ using Jetifier. Reason: 8. (Run with --stacktrace for more details.) To disable Jetifier, set android.enableJetifier=false in your gradle.properties file.
进而,带上–stacktrace看看。
./gradlew assembleDevDebug --stacktrace
…
…
Caused by: java.lang.ArrayIndexOutOfBoundsException: 8
at org.objectweb.asm.ClassReader.readFrameType(ClassReader.java:2313)
at org.objectweb.asm.ClassReader.readFrame(ClassReader.java:2269)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1448)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1126)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:698)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.android.tools.build.jetifier.processor.transform.bytecode.ByteCodeTransformer.runTransform(ByteCodeTransformer.kt:39)
at com.android.tools.build.jetifier.processor.Processor.visit(Processor.kt:328)
at com.android.tools.build.jetifier.processor.archive.ArchiveFile.accept(ArchiveFile.kt:41)
at com.android.tools.build.jetifier.processor.Processor.visit(Processor.kt:316)
at com.android.tools.build.jetifier.processor.archive.Archive.accept(Archive.kt:66)
at com.android.tools.build.jetifier.processor.Processor.visit(Processor.kt:316)
at com.android.tools.build.jetifier.processor.archive.Archive.accept(Archive.kt:66)
at com.android.tools.build.jetifier.processor.Processor.transformLibrary(Processor.kt:312)
at com.android.tools.build.jetifier.processor.Processor.transform(Processor.kt:175)
at com.android.build.gradle.internal.dependency.JetifyTransform.transform(JetifyTransform.kt:199)
… 39 more
我们发现,JetifyTransform内部使用了ASM,在对aar进行ClassReader的过程中抛出了异常。并且从错误栈信息上看,应该有一类叫jetifier
的工具,是在这个工具中调用的ASM操作。
官方文档搜索下,果然发现了jetifier
的踪迹。
developer.android.com/studio/comm…
同样的,Google Source上也找到了其对应的实现。
android.googlesource.com/platform/fr…
下载对应的jetifier-standalone
,解压后,执行命令对fingerprint-1.1.1.aar
执行AndroidX转化。
➜ bin ./jetifier-standalone -i ./fingerprint-1.1.1.aar -o 11.aar
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 8
at org.objectweb.asm.ClassReader.readFrameType(ClassReader.java:2313)
at org.objectweb.asm.ClassReader.readFrame(ClassReader.java:2269)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1448)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1126)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:698)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.android.tools.build.jetifier.processor.transform.bytecode.ByteCodeTransformer.runTransform(ByteCodeTransformer.kt:40)
at com.android.tools.build.jetifier.processor.Processor.visit(Processor.kt:539)
at com.android.tools.build.jetifier.processor.archive.ArchiveFile.accept(ArchiveFile.kt:53)
at com.android.tools.build.jetifier.processor.Processor.visit(Processor.kt:521)
at com.android.tools.build.jetifier.processor.archive.Archive.accept(Archive.kt:76)
at com.android.tools.build.jetifier.processor.Processor.visit(Processor.kt:521)
at com.android.tools.build.jetifier.processor.archive.Archive.accept(Archive.kt:76)
at com.android.tools.build.jetifier.processor.Processor.transformLibrary(Processor.kt:517)
at com.android.tools.build.jetifier.processor.Processor.transform2(Processor.kt:291)
at com.android.tools.build.jetifier.processor.Processor.transform2
d
e
f
a
u
l
t
(
P
r
o
c
e
s
s
o
r
.
k
t
:
251
)
a
t
c
o
m
.
a
n
d
r
o
i
d
.
t
o
o
l
s
.
b
u
i
l
d
.
j
e
t
i
f
i
e
r
.
s
t
a
n
d
a
l
o
n
e
.
M
a
i
n
.
r
u
n
(
M
a
i
n
.
k
t
:
156
)
a
t
c
o
m
.
a
n
d
r
o
i
d
.
t
o
o
l
s
.
b
u
i
l
d
.
j
e
t
i
f
i
e
r
.
s
t
a
n
d
a
l
o
n
e
.
M
a
i
n
default(Processor.kt:251) at com.android.tools.build.jetifier.standalone.Main.run(Main.kt:156) at com.android.tools.build.jetifier.standalone.Main
default(Processor.kt:251)atcom.android.tools.build.jetifier.standalone.Main.run(Main.kt:156)atcom.android.tools.build.jetifier.standalone.MainCompanion.main(Main.kt:109)
at com.android.tools.build.jetifier.standalone.Main.main(Main.kt)
发现出现了同样的错误信息。
显然,应该是fingerprint-1.1.1.aar
中有字节码有问题。经查,fingerprint内部直接以jar方式引入了三星的指纹识别库,已经很比较老的版本了,经业务同学确认,现在已经可以直接去除。
去除fingerprint内部的三星指纹库后,升级版本,下载对应的aar文件后,再次尝试转化:
./jetifier-standalone -i ./fingerprint-1.1.3-20190916.092208-1.aar -o mm.aar
执行成功,且有转换后的对应文件生成。
主工程更新fingerprint对应依赖版本后,重新执行构建,出现错误提示:
e: /Users/corn/AndroidStudioProjects/MyCorn/base/src/main/java/com/mycorn/base/mvvm/EventLiveData.kt: (13, 5): ‘observe’ overrides nothing
e: /Users/corn/AndroidStudioProjects/MyCorn/base/src/main/java/com/mycorn/base/mvvm/EventLiveData.kt: (20, 5): ‘removeObserver’ overrides nothing
原因在于对应的LiveData接口observe、removeObserver中的形参有所改动,从原来的
@NonNull Observer observer
变成了
@NonNull Observer<? super T> observer
修正EventLiveData类中的重写方法的对应形参,与接口保持一致即可。
再次重新构建,出现错误信息:
/Users/corn/AndroidStudioProjects/MyCorn/trans/src/main/java/com/mycorn/biz/supertrans/v12/slide/ItemSlideHelper.java:566: 错误: 程序包androidx.appcompat.recyclerview.R不存在
.getDimension(androidx.appcompat.recyclerview.R.dimen.item_touch_helper_swipe_escape_velocity);
/Users/corn/AndroidStudioProjects/MyCorn/trans/src/main/java/com/mycorn/biz/supertrans/v12/slide/ItemSlideHelper.java:568: 错误: 程序包androidx.appcompat.recyclerview.R不存在
.getDimension(androidx.appcompat.recyclerview.R.dimen.item_touch_helper_swipe_escape_max_velocity);
/Users/corn/AndroidStudioProjects/MyCorn/trans/src/main/java/com/mycorn/biz/supertrans/v12/slide/ItemSlideHelper.java:2115: 错误: 程序包androidx.appcompat.recyclerview.R不存在
androidx.appcompat.recyclerview.R.dimen.item_touch_helper_max_drag_scroll_per_frame);
核查官方文档,对应的替换关系应该是:
ndroid.support.v7.recyclerview.R
替换为
androidx.recyclerview.R
此处替换成了
androidx.appcompat.recyclerview.R
按照文档对应修正过来。
再次重新构建,可以构建成功。
3.4 核验与发现
此时构建成功,是不是就真的都处理好了呢,是不是都没问题了呢。显然不是的。
首先,分别查看主工程对应的编译时和运行时依赖,看看是否都从android.support.*
替换成了androidx.*
。
./gradlew -q MyCorn:dependencies --configuration devDebugAndroidTestCompileClasspath > ~/compile.txt
./gradlew -q MyCorn:dependencies --configuration devDebugAndroidTestRuntimeClasspath > ~/runtime.txt
仔细对比后发现,虽然依赖中都已经被替换成了androidx.*
。但编译时的依赖中含有大量的rc01
。如:
androidx.appcompat:appcompat:1.0.0-rc01
androidx.recyclerview:recyclerview:1.0.0-rc01
…
但运行时依赖中却没有rc01
。
androidx.appcompat:appcompat:1.0.0
androidx.recyclerview:recyclerview:1.0.0
…
经核查后发现,主工程中之前依赖支持库时有两种写法,一种是直接写法,如:
implementation 'com.android.support:appcompat-v7:28.0.0
另一种是采取统一定义后,进行的变量形式引入:
api rootProject.ext.dependencies[“appcompat-v7”]
其中,具体变量,如appcompat-v7
被统一定义在了专用的一个dependencies.gradle
文件中。
大致形式如下:
// 统一配置管理
def supportVersion = “28.0.0”
project.ext {
android = [
“compileSdkVersion”: 28,
“minSdkVersion” : 19,
“targetSdkVersion” : 26,
“javaMaxHeapSize” : “5G”
]
dependencies = [
“support-compat” : “com.android.support:support-compat:
s
u
p
p
o
r
t
V
e
r
s
i
o
n
"
,
"
s
u
p
p
o
r
t
−
c
o
r
e
−
u
t
i
l
s
"
:
"
c
o
m
.
a
n
d
r
o
i
d
.
s
u
p
p
o
r
t
:
s
u
p
p
o
r
t
−
c
o
r
e
−
u
t
i
l
s
:
{supportVersion}", "support-core-utils" : "com.android.support:support-core-utils:
supportVersion","support−core−utils":"com.android.support:support−core−utils:{supportVersion}”,
“support-core-ui” : “com.android.support:support-core-ui:
s
u
p
p
o
r
t
V
e
r
s
i
o
n
"
,
"
s
u
p
p
o
r
t
−
m
e
d
i
a
−
c
o
m
p
a
t
"
:
"
c
o
m
.
a
n
d
r
o
i
d
.
s
u
p
p
o
r
t
:
s
u
p
p
o
r
t
−
m
e
d
i
a
−
c
o
m
p
a
t
:
{supportVersion}", "support-media-compat": "com.android.support:support-media-compat:
supportVersion","support−media−compat":"com.android.support:support−media−compat:{supportVersion}”,
“support-fragment” : “com.android.support:support-fragment:
s
u
p
p
o
r
t
V
e
r
s
i
o
n
"
,
"
s
u
p
p
o
r
t
−
a
n
n
o
t
a
t
i
o
n
s
"
:
"
c
o
m
.
a
n
d
r
o
i
d
.
s
u
p
p
o
r
t
:
s
u
p
p
o
r
t
−
a
n
n
o
t
a
t
i
o
n
s
:
{supportVersion}", "support-annotations" : "com.android.support:support-annotations:
supportVersion","support−annotations":"com.android.support:support−annotations:{supportVersion}”,
“appcompat-v7” : “com.android.support:appcompat-v7:${supportVersion}”,
…
…
]
}
来到对应的文件,发现对应的android.support.*
并没有被替换成androidx.*
。
而在build.gralde
中直接引入的写法,是被相应替换了的。已经被正确替换成了:
implementation ‘androidx.appcompat:appcompat:1.0.0’
也就是说,构建时,遇到api rootProject.ext.dependencies["appcompat-v7"]
,其实是没有被准确识别的,按照编译时的依赖关系,最终被识别成了带有rc01
的AndroidX版本。
于是,才出现了编译时和运行时大量的版本不一致情况。
解决起来很简单,直接在dependencies.gradle
文件中,将android.support.*
对应人为替换成androidx.*
形式,并重新规范命名和版本,相应修正对应的被使用到的地方,并修正成统一的AndroidX依赖写法。
// 统一配置管理
def androidXVersion = “1.0.0”
project.ext {
android = [
“compileSdkVersion”: 28,
“minSdkVersion” : 19,
“targetSdkVersion” : 26,
“javaMaxHeapSize” : “5G”
]
dependencies = [
“androidx-core” : “androidx.core:core:
a
n
d
r
o
i
d
X
V
e
r
s
i
o
n
"
,
"
a
n
d
r
o
i
d
x
−
c
o
r
e
−
u
t
i
l
s
"
:
"
a
n
d
r
o
i
d
x
.
l
e
g
a
c
y
:
l
e
g
a
c
y
−
s
u
p
p
o
r
t
−
c
o
r
e
−
u
t
i
l
s
:
{androidXVersion}", "androidx-core-utils" : "androidx.legacy:legacy-support-core-utils:
androidXVersion","androidx−core−utils":"androidx.legacy:legacy−support−core−utils:{androidXVersion}”,
“androidx-core-ui” : “androidx.legacy:legacy-support-core-ui:
a
n
d
r
o
i
d
X
V
e
r
s
i
o
n
"
,
"
a
n
d
r
o
i
d
x
−
m
e
d
i
a
"
:
"
a
n
d
r
o
i
d
x
.
m
e
d
i
a
:
m
e
d
i
a
:
{androidXVersion}", "androidx-media" : "androidx.media:media:
androidXVersion","androidx−media":"androidx.media:media:{androidXVersion}”,
“androidx-fragment” : “androidx.fragment:fragment:
a
n
d
r
o
i
d
X
V
e
r
s
i
o
n
"
,
"
s
u
p
p
o
r
t
−
a
n
n
o
t
a
t
i
o
n
s
"
:
"
a
n
d
r
o
i
d
x
.
a
n
n
o
t
a
t
i
o
n
:
a
n
n
o
t
a
t
i
o
n
:
{androidXVersion}", "support-annotations" : "androidx.annotation:annotation:
androidXVersion","support−annotations":"androidx.annotation:annotation:{androidXVersion}”,
“androidx-appcompat” : “androidx.appcompat:appcompat:${androidXVersion}”,
…
…
]
}
重新输出编译时和运行时依赖,发现此时支持库版本已经一致。
重新构建项目,发现可以构建成功。
文末
当你打算跳槽的时候,应该把“跳槽成功后,我能学到什么东西?对我的未来发展有什么好处”放在第一位。这些东西才是真正引导你的关键。在跳槽之前尽量“物尽其用”,把手头上的工作做好,最好是完成了某个项目或是得到提升之后再走。跳槽不是目的,而是为了达到最终职业目标的手段
最后祝大家工作升职加薪,面试拿到心仪Offer
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
8j-1713679999972)]
[外链图片转存中…(img-rZrA7bft-1713679999972)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-bA5a5qn2-1713679999973)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!