Tencent / tinker

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

maindex超出最大方法数 #1369

Open YuTianTina opened 4 years ago

YuTianTina commented 4 years ago

Issue/提问须知

在提交issue之前,我们应该先查询是否已经有相关的issue以及常见问题。提交issue时,我们需要写明issue的原因,以及编译或运行过程的日志(加载进程以及Patch进程)。issue需要以下面的格式:

异常类型:app编译异常

tinker版本:如:1.9.14.5

gradle版本:如:4.10.1

是否使用热更新SDK:  TinkerPatch SDK

系统:Mac

堆栈/日志:
D8: Cannot fit requested classes in the main-dex file (# methods: 83641 > 65536 ; # fields: 160029 > 65536)

原来通过以下方法, 在1.9.13.2-可用, 升级.5版本后, 编译仍会报主dex超65536的问题 拦截tinkerProcessMultidexKeep, 使用自己的multiDexKeepProguard规则, 但是输出逇maindexfile, 包括Application#onCreate流程中引用到的所有类, 导致超出65536 规则如下

#tinker multidex keep patterns:
-keep public class * implements com.tencent.tinker.entry.ApplicationLifeCycle {
    <init>(...);
    void onBaseContextAttached(android.content.Context);
}

#-keep public class com.tencent.tinker.entry.ApplicationLifeCycle {
#    *;
#}

-keep public class * extends com.tencent.tinker.loader.TinkerLoader {
    <init>(...);
}

-keep public class * extends android.app.Application {
     <init>();
     void attachBaseContext(android.content.Context);
}

-keep class com.tencent.tinker.loader.TinkerTestAndroidNClassLoader {
    <init>(...);
}

#your dex.loader patterns here
-keep class 我的application代理类 {
    <init>(...);
}

-keep class com.tencent.tinker.loader.** {
    <init>(...);
}

-keep class com.tencent.tinker.entry.TinkerApplicationInlineFence{
    <init>(...);
}

不拦截的情况下, Tinker本身维护的multiDex的规则也仍然会报65536的编译问题

YuTianTina commented 4 years ago

当前通过和老版本的maindexfile比对, 排查多余的类信息, 在multidexlist task之前对maindexfile进行修改, 可以解决问题

icemanstudy commented 4 years ago

我也遇到了这个问题.使用的tinker版本是1.9.14.5.开启tinker之后maindex中class数量暴增.不过目前还没有确实是不是都来自于继承ApplicationLike的类的onCreate引用的类.

SenseLo commented 4 years ago

当前通过和老版本的maindexfile比对, 排查多余的类信息, 在multidexlist task之前对maindexfile进行修改, 可以解决问题

你好,当前我是版本1.9.9升级到1.9.14.5出现这个问题,打包失败出现这个问题 com.android.tools.r8.utils.AbortException: Error: null, Cannot fit requested classes in the main-dex file (# methods: 84036 > 65536),请问一下你的解决办法吧是啥?谢谢

pxc0215 commented 3 years ago

在 1.9.14.7 版,我再 gradle 中加入了以下任务解决了:

    tasks.whenTaskAdded { task ->
        android.applicationVariants.all { variant ->
            if (task.name == "tinkerProcess${variant.name.capitalize()}MultidexKeep") {
                task.finalizedBy "fixTinkerDexKeepProguardFor${variant.name.capitalize()}"
            }
        }
    }

    android.applicationVariants.all { variant ->
        Task fixTinkerDexKeepProguard = task("fixTinkerDexKeepProguardFor${variant.name.capitalize()}")
        fixTinkerDexKeepProguard.doLast {
            def tinkerMultidexKeepTask = project.tasks.findByName("tinkerProcess${variant.name.capitalize()}MultidexKeep")
            def multiDexKeepProguardFile = file(tinkerMultidexKeepTask.multiDexKeepProguard)
            def lines = []
            // 记录从某条规则开始,后面需要跳过几行
            def skipLines = 0
            multiDexKeepProguardFile.text.eachLine { line ->
                if (line.contains("-keep class com.tencent.tinker.entry.TinkerApplicationInlineFence")) {
                    skipLines = 2
                } else if (skipLines > 0) {
                    skipLines--
                } else {
                    lines.add(line)
                }
            }

            FileWriter fr = new FileWriter(multiDexKeepProguardFile, false)
            try {
                for (String line : lines) {
                    fr.write(line)
                    fr.write("\n")
                }
            } finally {
                fr.close()
            }
        }
    }

注意!!!该方法在 Android 5.0 以下设备不可用,会导致启动崩溃!Android 5.0 以上设备,试过两台,热更新功能可用。