DexOverflowException: Cannot fit requested classes in the main-dex file

后端 未结 4 1629
春和景丽
春和景丽 2021-01-15 19:23

I have quite big multi module, multi flavor multidex project, but recently I got error when trying to do command line build (assemble{flavor}Release)

Message is:

4条回答
  •  暖寄归人
    2021-01-15 19:38

    For release build you should try to fix that with proguard. For debug you can try to fix it by excluding some classes from main dex file.

    Add this to the application module

       import your.awesome.app.MainDexGenerator
    
       tasks.whenTaskAdded {
                if (it.name.contains('transformDexArchiveWithDexMergerFor') && it.name.contains('Debug')) {
                    it.doFirst(new MainDexGenerator([
                            'io/reactivex/annotations',
                            'kotlin',
                            'com/fasterxml'
                            //....and other you think could work 
                    ]))
                }
            }
    

    you can find classes that gradle wants to add to main dex in: intermeditates/legacy_multidex_main_dex_list/. For example you can exclude unused models or something else, basically everything you don't need when Application class is starting. Do not forget to check that you didn't broke anything on API 19 or lower

    set up buildSrc with build.gradle with groovy plugin.

    At buildSrc/main/groovy/your/awesome/app add your action:

    @CompileStatic
    class MainDexGenerator implements Action {
    
        private static final String MAIN_DEX_FILE = 'mainDexList.txt'
    
        // list we want to exclude frome MainDex
        private List excludedList
        MainDexGenerator(List excludedPackages) {
            excludedList = excludedPackages;
        }
    
        @Override
        void execute(Task task) {
            for (File inputFile : task.inputs.files.files) {
                if (inputFile.absolutePath.endsWith(MAIN_DEX_FILE)) {
                    List result = Files.lines(inputFile.toPath())
                            .filter { isNotMatch(it) }
                            .collect(Collectors.toList())
                    Files.write(inputFile.toPath(), result, WRITE, TRUNCATE_EXISTING)
                    break
                }
            }
        }
    
        private boolean isNotMatch(String line) {
            for (String item : excludedList) {
                if (line.contains(item)) {
                    return false
                }
            }
            return true
        }
    }
    

    Too see the resulting method count you can use apkAnalyzer tool. Look for first dex.

    Also you can try to refactor your code and extract some responsibilities from application class.

    You can also try to increase minApi to 21.

    This answer has some more details on the problem Too many classes in --main-dex-list, main dex capacity exceeded

提交回复
热议问题