Ugh, this error again. I’ve run into it a bunch of times myself, and it’s pretty annoying.
A little background: “dex” stands for “Dalvik executable,” and a dex file contains compiled Java code. Dalvik was the old runtime environment used on Android (last used in version 4.4). The new version (ART, or Android Runtime) uses the same executable files.
OpenFL apps mostly use C++ code (which is compiled to
.so files, not
.dex ones), but they do use some Java. OpenFL extensions (like this Heyzap extension) use primarily Java. The app itself produces one dex file, and each extension produces another. Then the build tool merges all of these dex files together into one file, and that one file is what gets run when you launch the app.
Note: a single dex file can have a maximum of 65536 methods (equal to 64 * 1024, hence “64K”). If you hit this limit, you either have to reduce the number of methods (recommended, because you probably aren’t using all of them) or use multiple dex files (not recommended because it slows the build process significantly).
When the dex merger merges the small dex files into a single big one, it looks at method names and signatures. If two methods have different names, then it includes them both. If two methods have the same name but different signatures, that’s fine too, so it includes both. (Java supports method overloading.)
If two methods have the same name and signature (and they’re in the same class), then you have a potential conflict. I believe that this is still fine as long as the contents of the method are the same. If so, then the merger just uses one. But if you have two methods with indistinguishable signatures that do different things, there’s nothing the merger can do, so it throws the “multiple dex files define” error.
What you have to do is figure out which two files define that method, and then either delete one or make them match.
When dealing with the Google Play Services, you can get this error by including different versions. Each piece of the services includes some common methods (the “Google Play Services basement”), and these common methods have changed slightly over time. Therefore, if you include Google+ version 9.2.0 and Google Location services 9.4.0, you get two slightly-different versions of the common methods. The merger can’t reconcile these methods, so it crashes. All you have to do is use the same version of the two, and the error goes away.
Some libraries try to make your life easier by giving you a precompiled jar that you can just “drop in” to your project. That way, you don’t have to bother compiling the actual source. That’s all well and good until the library decides to distribute the jar and the source code in the same download, and you compile the whole thing. Now you have two compiled versions of the library’s code, except they were compiled on different computers, probably using different versions of Java. And the two versions will definitely be very close, but there’s no way they’ll be 100% identical, and so the dex merger will fail. The solution? Just delete that jar.
Sometimes, you can end up doing this to yourself. OpenFL creates an Android project by copying files into your
bin/android/bin folder, but if you change the name or location of a file, it won’t delete the old one. This means it’s actually pretty easy to end up with old files alongside new ones, which is an excellent way to cause this error. If this happens, all you need to do is delete
bin/android/bin and recompile.
This is one of those hard-to-track-down errors that’s easy to fix once you track it down. The really frustrating part is that the dex merger doesn’t tell you which dex files were in conflict, so you have to guess based on the method in question. In this case, it’s related to Heyzap, so that presumably narrows it down.
bin/android/bin doesn’t help, download 7-Zip and start looking through your jar files for the
AbstractFuture$Sync class. (Also check for Java files named
AbstractFuture.) Once you find two of them, take a guess as to which one is safer to delete.