9

I am doing some hacking on Jan Berkel's SBT Android Plugin and I was wandering if there is a way to merge multiple .dex files into one .dex file that will contain all of them.

For example, if I have this:

classes1.dex
classes2.dex
classes3.dex

Is there any way to merge them using Scala (in some acceptable time) to one single classes.dex file that will contain all 3 of them and have a following structure:

classes.dex
|-- classes1/...
|-- classes2/...
\-- classes3/...
ioreskovic
  • 5,531
  • 5
  • 39
  • 70

5 Answers5

6

OK, it seems I found something.

import com.android.dx.io.DexBuffer
import com.android.dx.DexMerger
import com.android.dx.merge.CollisionPolicy
...
val dexA = DexBuffer(File(classes1DexFilePath))
val dexB = DexBuffer(File(classes2DexFilePath))
val dexMerger = DexMerger(dexA, dexB, CollisionPolicy.FAIL)
val dexM = dexMerger.merge()
dexM.writeTo(File(classesDexFilePath))

Could anyone verify this is indeed working?

Also, if this works, then merging more than 2 dex files should be the same as Max(Max(A, B), C), providing you write a method that with a prototype
DexBuffer merge(DexBuffer dexA, DexBuffer dexB)

Sources:
DexMerger
DexBuffer
CollisionPolicy

ioreskovic
  • 5,531
  • 5
  • 39
  • 70
3

I found a way which don't need to compile from source, just use the SDK compiled jar.

java -cp dx.jar com.android.dx.merge.DexMerger output.dex input1.dex input2.dex

The dx.jar is located in Android SDK dir, like android\sdk\build-tools\26.0.2\lib. The dex file have 64k method limit, so it can't hold so much in one dex file.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
bob dawson
  • 91
  • 5
1

it's working. r22 uses this way to pre-dex android-support-v4.jar and annotations.jar into dex format first. Ant then use dx.bat to merge them with the compiled .class files.

colordancer
  • 162
  • 8
0

First zip them individually like classes1.dex.zip, classes2.dex.zip, classes3.dex.zip and then run following

java -jar dx.jar --dex --output=classes.dex.zip classes1.dex.zip classes2.dex.zip classes3.dex.zip

That's it. Now you have a classes.dex in classes.dex.zip with classes1.dex.zip classes2.dex.zip classes3.dex.zip are merged.

HemanthJabalpuri
  • 344
  • 4
  • 11
  • I tried zipping them and that didn't make any difference from when I didn't zip them so I don't think that zipping them is necessary – ZiyadCodes Aug 27 '22 at 20:27
0

The not outdated method

Just in case anyone stumbled on this question like I did, all of these answers are outdated by now (I'm only talking about the answers answered before this one in this question)

The current method to merge dex files is this:

d8 classes1.dex classes2.dex classes3.dex

dx has been renamed as d8

Now it's a lot simpler and cleaner

d8 can be found (in windows) in C:\Users\$your_user\AppData\Local\Android\Sdk\build-tools\$version\d8

You can merge any amount of dex files together, but:

The maximum method amount of a dex file is 65,536 (Which is equal to 64K, A K is equal to a kilo which is equal to 1024)

If you face that problem then this link might be helpful. The conclusion of the link was that you should use the --multi-dex option. So the command will look like this:

d8 --multi-dex classes1.dex classes2.dex classes3.dex

and that you need to add the line

multiDexEnabled true

in the module/build.gradle file in the defaultConfig so it would look like this:

android {
    ...

    defaultConfig {
        ...
    
        // Enabling multidex support.
        multiDexEnabled true

        ...
    }

    ...
}

I hope this helped

ZiyadCodes
  • 379
  • 3
  • 10