Tencent / tinker

Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.
Other
17.17k stars 3.34k forks source link

debug 补丁:Warning:ignoreWarning is false, but we found loader classes are found in new secondary dex. #586

Closed chinnsenn closed 7 years ago

chinnsenn commented 7 years ago

异常类型:编译异常

tinker版本:1.8.1

gradle版本: 2.3.0

是否使用热更新SDK: 否

系统:Windows 10

堆栈/日志: -----------------------Tinker patch begin----------------------- configuration: oldApk:D:\Work\Android\AS-Jambo\app\build\bakApk/app-debug-3.2.33-0829-08-55-52.apk newApk:D:\Work\Android\AS-Jambo\app\build\outputs\apk\app-debug.apk outputFolder:D:\Work\Android\AS-Jambo\app\build\outputs/tinkerPatch/debug isIgnoreWarning:false isProtectedApp:false 7-ZipPath:C:\Users\chuan.gradle\caches\modules-2\files-2.1\com.tencent.mm\SevenZip\1.1.10\4786999cf29d8e3b0c39a80359b5127bda36132a\SevenZip-1.1.10-windows-x86_64.exe useSignAPk:true package meta fields: filed name:patchMessage, filed value:tinker is sample to use filed name:platform, filed value:all filed name:patchVersion, filed value:1 dex configs: dexMode: jar dexPattern:assets/secondary-dex-..jar dexPattern:classes..dex dex loader:com.jianbao.doctor.MainApp dex loader:com.tencent.tinker.loader. dex loader:tinker.sample.android.app.BaseBuildInfo lib configs: libPattern:lib/./..so resource configs: resPattern:res/. resPattern:resources.arsc resPattern:AndroidManifest.xml resPattern:assets/. resIgnore change:assets/sample_meta.txt largeModSize:100kb useApplyResource:true

Analyze old and new apk files: old apk: app-debug-3.2.33-0829-08-55-52.apk, size=35893986, md5=de73d5341fe9d8f58d79aca0fe202ef3 new apk: app-debug.apk, size=43110646, md5=68e56f40ed8763718353524e47fde75a UnZipping apk to D:\Work\Android\AS-Jambo\app\build\outputs\tinkerPatch\debug\app-debug-3.2.33-0829-08-55-52 UnZipping apk to D:\Work\Android\AS-Jambo\app\build\outputs\tinkerPatch\debug\app-debug Check for loader classes in dex: classes.dex Check for loader classes in dex: classes2.dex Check for loader classes in dex: classes3.dex Warning:ignoreWarning is false, but we found loader classes are found in new secondary dex. Found classes: {Lcom/tencent/tinker/loader/TinkerResourcesKey$V17;,Lcom/tencent/tinker/loader/shareutil/ShareResPatchInfo;,Lcom/tencent/tinker/loader/SystemClassLoaderAdder$V23;,Lcom/tencent/tinker/loader/shareutil/ShareBsDiffPatchInfo;,Lcom/tencent/tinker/loader/shareutil/ShareOatUtil$1;,Lcom/tencent/tinker/loader/shareutil/ShareOatUtil;,Lcom/tencent/tinker/loader/shareutil/SharePatchFileUtil;,Lcom/tencent/tinker/loader/shareutil/ShareFileLockHelper;,Lcom/tencent/tinker/loader/shareutil/ShareReflectUtil;,Lcom/tencent/tinker/loader/TinkerDexOptimizer$StreamConsumer$1;,Lcom/jianbao/doctor/MainApp;,Lcom/tencent/tinker/loader/TinkerDexLoader;,Lcom/tencent/tinker/loader/TinkerUncaughtHandler;,Lcom/tencent/tinker/loader/TinkerDexOptimizer$1;,Lcom/tencent/tinker/loader/TinkerDexOptimizer;,Lcom/tencent/tinker/loader/TinkerDexOptimizer$StreamConsumer;,Lcom/tencent/tinker/loader/app/DefaultApplicationLike;,Lcom/tencent/tinker/loader/shareutil/ShareConstants;,Lcom/tencent/tinker/loader/AndroidNClassLoader;,Lcom/tencent/tinker/loader/TinkerResourcesKey;,Lcom/tencent/tinker/loader/shareutil/SharePatchInfo;,Lcom/tencent/tinker/loader/shareutil/ShareIntentUtil;,Lcom/tencent/tinker/loader/SystemClassLoaderAdder$V14;,Lcom/tencent/tinker/loader/TinkerResourcesKey$V24;,Lcom/tencent/tinker/loader/TinkerTestAndroidNClassLoader;,Lcom/tencent/tinker/loader/shareutil/ShareOatUtil$InstructionSet;,Lcom/tencent/tinker/loader/shareutil/ShareElfFile$SectionHeader;,Lcom/tencent/tinker/loader/app/TinkerApplication;,Lcom/tencent/tinker/loader/TinkerDexOptimizer$ResultCallback;,Lcom/tencent/tinker/loader/TinkerResourceLoader;,Lcom/tencent/tinker/loader/SystemClassLoaderAdder$V19;,Lcom/tencent/tinker/loader/shareutil/ShareResPatchInfo$LargeModeInfo;,Lcom/tencent/tinker/loader/TinkerRuntimeException;,Lcom/tencent/tinker/loader/TinkerResourcesKey$V19;,Lcom/tencent/tinker/loader/shareutil/ShareElfFile$1;,Lcom/tencent/tinker/loader/TinkerDexLoader$1;,Lcom/tencent/tinker/loader/TinkerTestDexLoad;,Lcom/tencent/tinker/loader/shareutil/ShareElfFile$ProgramHeader;,Lcom/tencent/tinker/loader/TinkerSoLoader;,Lcom/tencent/tinker/loader/shareutil/ShareElfFile$ElfHeader;,Lcom/tencent/tinker/loader/app/ApplicationLifeCycle;,Lcom/tencent/tinker/loader/TinkerResourcePatcher;,Lcom/tencent/tinker/loader/shareutil/ShareTinkerInternals;,Lcom/tencent/tinker/loader/R;,Lcom/tencent/tinker/loader/TinkerDexOptimizer$OptimizeWorker;,Lcom/tencent/tinker/loader/BuildConfig;,Lcom/tencent/tinker/loader/TinkerLoader;,Lcom/tencent/tinker/loader/SystemClassLoaderAdder$V4;,Lcom/tencent/tinker/loader/app/ApplicationLike;,Lcom/tencent/tinker/loader/shareutil/ShareSecurityCheck;,Lcom/tencent/tinker/loader/AbstractTinkerLoader;,Lcom/tencent/tinker/loader/SystemClassLoaderAdder$1;,Lcom/tencent/tinker/loader/TinkerResourcesKey$V7;,Lcom/tencent/tinker/loader/shareutil/ShareDexDiffPatchInfo;,Lcom/tencent/tinker/loader/shareutil/ShareElfFile;,Lcom/tencent/tinker/loader/SystemClassLoaderAdder;}

liyuzero commented 7 years ago

1.8.1,出现了同样的问题。反编译解包后发现,在tinkerPatchDebug命令下生成的app-debug包,将原有的三个dex文件,如dex1,2,3,复制变成了6个即:dex1,2-6,。即,新增的三个dex文件和原有的三个dex文件是分别对应相等的,导致了检验不通过。把ignoreWarning设置为true可以热更新成功,但是补丁包太大。。。

chinnsenn commented 7 years ago

@liyuzero 我也试了一下,确实如此。一个补丁 5.4 M,我就改了 XML 里的一个字符串。

liyuzero commented 7 years ago

执行tinkerPatchDebug操作之后,你的outputs\apk文件夹下新生成的apk文件经解压后,dex也会出现重复吗?

chinnsenn commented 7 years ago

@liyuzero 嗯,我是 两个 classes.dex 变成 4 个

chinnsenn commented 7 years ago

@liyuzero 不过我这里虽然提示 pacth 成功,但是重启还是不会生效

liyuzero commented 7 years ago

应该是进程没杀掉的原因,拿手机清理工具杀一下就好了应该。但是没什么意义,补丁包太大了。不知道作者什么时候能解答一下。自己的测试的分包项目没问题,但是在实际项目中就出现这个问题了。

chinnsenn commented 7 years ago

@liyuzero 解决了 我注释了 pattern 里的配置

        dex {
            dexMode = "jar"
            pattern = [
//这里注释掉了
//                    "classes*.dex",
//                       "assets/secondary-dex-?.jar"
            ]
            loader = [
            ]
        }

然后把 ignoreWarning false 成功打补丁(4kb)

新生成的 apk dex 数量确实是原来的两倍

liyuzero commented 7 years ago

@foreveronly 确实可以。

但是考虑这种情况,就是你打补丁之后,由于方法数增加,apk中的dex数量增加了,这时候如果注释掉这句话,最后生成的补丁是错误的,也就是新增的dex文件中的类并没有被添加进补丁中。

经过测试【在我自己的分包测试项目中不会报这个错误,新生成的apk的dex文件也不会重复,所以无论注不注释都可以生成补丁。。。。】,我在测试的分包项目中添加一个新类,它包含55536个方法,大小为1.47M,注释掉pattern后生成的补丁只有2kb【有问题】,而不注释这句话,生成的补丁大小为600kb【正常】。

所以,我觉得这个pattern被注释掉后【注释里说的是会用pattern里的dex文件合成补丁,classes*.dex表示匹配所有dex文件】,tinker在生成补丁时就不会利用新增的dex文件来进行生成,而只会用原有的dex文件生成补丁,所以在补丁版本不改变dex数量的情况下,注释掉这句话确实没问题,但是万一修改项目后刚好新增了dex文件,那生成的补丁就会有问题了。

纯测试的,不知道理解的有没有问题。

chinnsenn commented 7 years ago

@shwenzhang

shwenzhang commented 7 years ago

ignoreWarning不建议改成true,注释跟之前的类似issue已经写得很清楚了。应该是你们自己项目用了其他的分包工具导致自动分配失效,所以需要手动配置main dex pattern,当改动比较大可以把keepdexapply打开

chinnsenn commented 7 years ago

@shwenzhang 帮忙看下

liyuzero commented 7 years ago

@foreveronly 我找到我出问题的原因了,我打开了keepDexApply模式,关掉之后就可以了。

chinnsenn commented 7 years ago

@liyuzero
还真是。。。

shwenzhang commented 7 years ago

keepDexApply这个问题我看看