【Tinker】踩坑之路(1)
1、找不到 variantConfiguration
No such property: variantConfiguration for class: com.android.build.gradle.internal.variant.ApplicationVariantData
https://github.com/Tencent/tinker/issues/1357
- 降低 build:gradle 版本,之前是 4.1.0
classpath “com.android.tools.build:gradle:3.5.3”
2、tinkerId is not set!!!
- 变量生成放在最前面
tip:偶现,概率较小,清理项目重启 AndroidStudio 又好了,那就这样吧!
3、Cannot get property ‘tinkerId’ on extra properties extension as it does not exist
-
build.gradle
中变量声明放在文件最前面
4、buildConfigField 指定参数,BuildConfig 类生成的字符串赋值错误
错误示例:
正确示例:
- 字符串得加转义字符
5、Tinker Exception:createInlineFence failed
启动闪退 Unable to instantiate application SampleApplication
我是通过重写 DefaultApplicationLike
设置注解 @DefaultLifeCycle(application = "com.example.tinkerdemo.SampleApplication")
- 忘记修改 AndroidManifest application 标签 name 属性值导致,改成与上述值保持一致即可,注解指定的 Applicantion 类在构建过程中由 gradle 生成
6、isIgnoreWarning=false,补丁构建失败
Warning:ignoreWarning is false, manifest was changed, while hot plug component support mode is disabled. Such changes will not take effect
- 把
isIgnoreWarning=true
设置为 true,查看源码你会发现,某些情况下当 isIgnoreWarning=false 时会触发异常并终止apk构建
7、找不到 com.tencent.tinker.loader.TinkerLoader 类
通常我们的 Android 工程配置文件是写在 proguard-rules.pro
,当然 Android 打包是支持自定义混淆文件的,而 Tinker 的混淆规则声明在文件 tinker_multidexkeep.pro
- 配置混淆规则
tinker_multidexkeep.pro
8、混淆打包没有输出 seed.txt、usage.txt、configuration.txt 文件
打混淆包或者有自定义混淆需求的,为了后期方便排查闪退等问题,通常都会保留混淆规则文件和混淆映射文件
- 配置混淆规则
-printconfiguration build/outputs/mapping/release/configuration.txt
-printusage build/outputs/mapping/release/usage.txt
-printseeds build/outputs/mapping/release/seed.txt
9、资源ID R.txt 文件在哪里?
是的,Tinker 在 build.gradle 已经编写了拷贝 R.txt 的脚本,一开始没注意到,不知者无罪可原谅
- 在这里
build/intermediates/symbols/release/R.txt
10、加载补丁失败 open failed: EACCES (Permission denied)
/storage/emulated/0/patch_signed_7zip.apk: open failed: EACCES (Permission denied)
嗯!!我发现在有些手机上是没有这个问题的(当然是已经动态申请并允许的读写权限
),那就有可能是与不同 Android 版本有关系了,我们也知道为了更好保护隐私,每次 Android 版本发布可能会对权限或存储区域做调整或限制
- 在 AndroidManifest Applicantion 标签配置
android:requestLegacyExternalStorage="true"
11、启动闪退 ApplicationLike 找不到
- 确认继承自 DefaultApplicationLike 类的 DefaultLifeCycle 注解配置的 application 一致
12、本地依赖错误 Annotation processors must be explicitly declared now
- 开放注解处理器(build.gradle 中配置),并添加依赖
defaultConfig{
//fix: Annotation processors must be explicitly declared now
javaCompileOptions {
javaCompileOptions {
includeCompileClasspath true
}
}
}
//根据《模块依赖关系图》可知,通过注解方式代理 Applicantion 生命周期是需要这个模块的
api project(path: ':tinker-android:tinker-android-anno')
compileOnly project(path: ':tinker-android:tinker-android-anno-support')
13、创建 native libary 构建报错:compileSdkVersion is not specified.
我的 Android Studio 版本比较高,默认创建 native libary 就给了这样的配置,所以我注释掉了(懂的可以评论)
-
compileSdkVersion
29 要写在最前面?
14、创建 native library 构建报错:Could not get version from cmake.dir path
- 配置正确的 ndk 路径:
C:\Users\YTS\AppData\Local\Android\Sdk\ndk\21.4.7075529
15、补丁ID不匹配:tinkerId in patch is not matched with the one in base pack
- 一定要注意了,生成补丁的基准包ID要一致
16、so 库修复失败
install: dexPathList =
DexPathList[
[zip file "/data/user/0/com.primer.applist/tinker/patch-94a56af5/dex/tinker_classN.apk"],
nativeLibraryDirectories=[
/data/user/0/com.primer.applist/tinker/patch-94a56af5/lib/lib/arm64-v8a,
/data/app/com.primer.applist-eUclB535uPmsCLlbgnyWDw==/lib/arm64,
/data/app/com.primer.applist-eUclB535uPmsCLlbgnyWDw==/base.apk!/lib/arm64-v8a,
/system/lib64,
/hw_product/lib64,
/system/product/lib64,
/prets/lib64]]
after hack classloader:
com.tencent.tinker.loader.TinkerClassLoader
[DexPathList[
[zip file "/data/user/0/com.primer.applist/tinker/patch-94a56af5/dex/tinker_classN.apk"],
nativeLibraryDirectories=[
/data/user/0/com.primer.applist/tinker/patch-94a56af5/lib/lib/arm64-v8a,
/data/app/com.primer.applist-eUclB535uPmsCLlbgnyWDw==/lib/arm64,
/data/app/com.primer.applist-eUclB535uPmsCLlbgnyWDw==/base.apk!/lib/arm64-v8a,
/system/lib64,
/hw_product/lib64,
/system/product/lib64,
/prets/lib64]]]
一大堆日志看得头晕,问题是什么呢:
生成补丁包之后,
先加载补丁文件,待加载成功后再加载 so库,
我可是按照 demo 调用 TinkerLoadLibrary.installNavitveLibraryABI(context,"arm64-v8a")
紧接着调用 System.loadLibrary
,
查看日志确认已经把补丁的 so 库路径插入到 nativeLibraryPathElements
数组第一个位置(看Tinker源码是通过反射插入 lib 路径,这也有 Android 源码你可以看看 https://android.googlesource.com/platform/libcore/+/master/dalvik/src/main/java/dalvik/system/DexPathList.java),
可为什么没有生效呢?
- 在 application 调用
TinkerLoadLibrary.installNavitveLibraryABI(getApplication(), abi);
然后再调用System.loadLibrary("nativelib");
(我猜之前没生效是我加载 so 时机不对,就先这样处理吧)
17、build/jar
生成的 tinker-patch-cli.jar 无法运行
原因: java.lang.NoClassDefFoundError: com/tencent/tinker/build/patch/Runner
也真真实奇怪,构建 patch-cli
工具 jar 怎么可能只有 6kb,没开玩笑吧!
错误的:
正确的:
- 使用
buildTinkerSdk
生成构建工具
对于新手的我,‘坑’不止于此,后续还有