Android running/testing speed and possible improvements


I wanted to ask you how do you efficient do to testing your application in an Android device. I have my Galaxy Nexus, and I can run the game on it, but I’m facing some problems. Whenever I want to test the game, I need to Clean and Build the mobile project (or Build or CleanAndBuild the game project) to update the generated apk.

But every time I do that, all the libraries are pre-dexed again, and this process takes really a long time to finish. Although I make no changes to those libraries, they are recalculated (my guess is some kind of hash function) when not needed.

This should happen if I Clean and Build (which deletes everything, no matter if from Mobile or Game project [correct behaviour]), but I thought that just Build the project wouldn’t do that (and it does uses the previously calculated jars). My thoughts were correct in a certain way:

When I build the Mobile project, he uses the previous calculated libraries, but the thing is the actual game jar (the one containing my game logic) doesn’t get update when just Build the Mobile project. If I Clean and Build the mobile project, as everything gets deleted, takes a long time to build. But if I just Build the Game project, I get a new updated jar with the game logic, but every other library get’s pre-dexed again, taking a long time to build it. The Clean and Build project on the Game project has the same behavior as the Build.

Question: How do you find a turn around on that? Can I use the previously calculated things to speed up my building process? Can I generate my new game logic jar without having to pre-dex (?) all the libraries again?

As far as I see, there are some major steps that are done for this:

  • Initial stuff (1 second)
  • Pre-dexing libraries (50 seconds)
  • Merge/create apk (3 seconds)
  • Finish stuff (1 seconds)
  • Uploading and installing the in the Android Device (4-5 seconds)

Also, I wanted to report some strange behavior I'm facing. Please review this section below and see if this is the intended/expected behavior.

Say I make some changes on my game, then:
- I Build or CleanAndBuild the Mobile project -> I an updated APK in MOBILE/BIN folder
- I Build the Game project -> I get a MyGame-release-unsigned.apk which I can't install on my device
- I CleanAndBuild the Game project -> I get a new and but not updated APK in the DIST folder (doesn't reflect my new code changes)
- I CleandAndBuild first the mobile project and then the Game project -> I get the new APK in the DIST folder (finally)

Idk, I once tried not copying the jar files again but even if they stay the same, googles build script decides to re-dex anyway, complain to google.

I can’t really reproduce what you say in the last sentence, you should never have to build the mobile project separately. What code changes? In the main project or the android harness?

When I mean code changes I mean in the game logic, like changing my SinpleApplicattion extension. Whenever I do some changes in that, I need to Build the project again to generate the APK with the code changes, and this takes a bit too much. Maybe I shouldn’t be testing with so much frequency in the Android, maybe just test in the android from time to time.

Yeah, you can just start the app normally in desktop mode when testing application / game flow stuff. This is unavoidable really, also for iOS etc in the future, there will always have to be the cross-compilation first.

I am afraid there’s no way of avoiding it… To generate the app’s APK file, it needs to combine all the classes in the classpath and create a classes.dex file. The only way I can see of speeding it up is by using an optimizing obfuscator like ProGuard which would cull out unused parts of the jME3 libraries prior to the dex conversion process.

@Momoko_Fan said:
I am afraid there's no way of avoiding it... To generate the app's APK file, it needs to combine all the classes in the classpath and create a classes.dex file. The only way I can see of speeding it up is by using an optimizing obfuscator like ProGuard which would cull out unused parts of the jME3 libraries prior to the dex conversion process.

This is all part of googles build process so theres nothing we can do to improve this situation unless google makes its build script more intelligent. As said, I tried keeping the exact versions of the files it used before and it still commences to re-create the dex.

I can see this happening if somehow you can just generate the JAR for the game logic (e.g. MyGame.jar) and you can put it inside the mobile project and ask the google builder to build it again, it will check that every other file is the same except for this new MyGame.jar and then it will just create the new dex for this jar and combine with the previous values (of course I may be wrong).

Like I said, no thats not what happens.

My Solution: Raid 0 a pair of SSD Hard Drives.

Don’t keep anything non-backed-up on a raid 0 drive of course but it makes for a real difference in compile times etc.

I don’t think the issue is in harddrive read speeds, after all, jar files are only a few MBs. I think its probably the conversion between java bytecode → dex bytecode not being very efficient, and thus when a huge amount of code is thrown at it (think jme3 + nifty + jbullet + blender loader + other stuff) it takes a long time.

It’s more seek times than anything else - accessing all the small files. I found compile times went down significantly moving to SSD. One project I worked on went from 15 minutes to around 7 for a full build including running unit tests. I can’t isolate the variables as there were other upgrades at the same time but the SSD certainly helped.

I’m sure an SSD would help, but I just gave up testing on the Android frequently and I’ll move onto the batch test on it (search for lots of things to test for single build). Small tests I do on the computer. Thanks for the clarification @normen

What i do is to test on desktop, and when every thing work i test on the device.

Also the upload time of the application to the device can be quite long, so using only necessary jars and assets can make a difference.