APK performance is inconsistent when compiled from different machines


#1

I have a strange problem, I’m currently ran out of ideas about what else I can try,

I’m trying to run and deploy my project from different computers to the same device,

when the app is launched after deployed from one PC, it works smoothly, when from other PC, the whole app behaves very very slow, even changing activity looks very laggy, my starting page is showing some animation and it looks like the animation works about X10 times slower!

What things in the development environment can affect the final apk??

All computers are running win 10,
with the same AS version (3.2),
AS checked to use embedded jdk (same java version),
Code is fetched from git to the same commit,
I run the same flavor (debug)
and the same real device (not emulator)

[I even tried to compare the final apk’s with classyshark, didn’t notice anything]


#2

I would start by ensuring that your tests are identical:

  • Reboot the device and uninstall the app between tests
  • Test the behavior on multiple devices, if you have them
  • Test in both directions (slow, then fast; fast, then slow)

If you are absolutely convinced that the problem is tied to one development machine:

  • Take a look at the APKs created by each (e.g., via APK Analyzer) and get a sense for how different they are
  • Use tools like systrace to see what is going on in the device when you are running the slow app
  • Check Logcat for stack traces of relevance, and consider adding your own logging to get an idea of where your time is being spent

If you are using a standard Android Studio Gradle-based project, and both development machines have the same JDK, then one thing that might vary would be dependencies, if one has a bad copy of a dependency somehow. You can clear the Gradle dependency cache to see if that clears up the problem.


#3

Thanks for the detailed answer.

I have tried most of your suggestions,

  • Reboot and uninstall - no change
  • Multiple devices - I have many devices but I see the problem only on the oldest devices, it is hard to notice on high performance devices
  • Test both direction - not sure what it means
  • Invalidating cache - did it on both machines and both still with no change (the “good” remain good and the “bad” remain bad)

Now about the APK analyzer - I opened the “good” APK in this tool and then chose compare and selected the “bad” APK, now I see one difference and I’m not sure what it means.
In one APK there is classes.dex 8MB and classes2.dex 891KB
In the other APK the classes.dex is 891KB and the classes2.dex is 8MB
Does it mean anything?
(I also see total size difference of 7KB but I will double check about it because except the classes files all other files are with zero difference)

And about logs and systrace it’s the next thing I’m going to check


#4

In your original question, you deployed from the good PC, then deployed from the bad PC. I am interested to know what happens if you start with the bad PC, then deploy from the good PC. If the problem is tied to the PC, the symptoms will be based on the “good”/“bad” element. If the problem goes away for the bad PC but shows up for the good PC, then neither PC is “bad” or “good”, but instead the problem is “the second PC”.

Does it mean anything?

That’s interesting. I try to avoid multidex to the greatest extent possible. AFAIK, classes.dex is the one that is loaded when your app starts, and other DEX files are loaded on demand. In the “classes.dex is 891KB and the classes2.dex is 8MB” scenario, I can see perhaps a one-time slowdown while classes2.dex is loaded, but I would not expect a long-term performance issue from it.


#5

Test both direction - It is consistent, I can switch several times between good and bad PC and it remains ok from the good and bad from the bad

I build the APK again from both machines after rebuild and compared again, now the dex are not different but I saw about 500B different in total size of the APK, then I checked the “compare file by file” in the analyzer tool and there are some more file differences.
You can see the different files in the attached screenshotimage


#6

If you do not have your own NDK code in the project, then the lib/ contents are coming from dependencies, as may part of your classes2.dex.

Invalidating cache - did it on both machines and both still with no change (the “good” remain good and the “bad” remain bad)

You used the term “invalidating cache”. That suggests that you used the Android Studio “Invalidate Caches / Restart” menu option. I do not know if that clears the Gradle dependency cache.


#7

No, I don’t have my own NDK.
And yes, I used the Android studio Invalidate cache and restart option,
How can I clear the Gradle cache?


#8

This Stack Overflow question and its answers go into various options.


#9

Thanks.

Cleared the Gradle cache from the “bad” PC, it’s still bad
I’m afraid to clear it on the good one I have a feeling it will have the problem too

I ran systrace one the same decvice one time on good compilation and second on bad compilation, the report looks different but one thing is more strange,
In systrace html report, the second section is “kernel”
In the bad report there is CPU 0 and CPU 3
In the good report there is CPU 0, CPU 1, CPU 2, CPU3


#10

I do not know of anything that you could have on the “bad” PC that would cause an app created by it to use fewer cores than the same app built on the “good” PC. The number of cores should be driven by the number and priority of threads that you create.

Does your Gradle build script, or anything else about your build process, pull in data that is not part of the project itself? Examples include:

  • Environment variables
  • Files that are not checked into version control (e.g., local properties files that contain data like signing keys)

If your build process uses these things, see if there are any differences between the data on the two PCs.


#11

No, I don’t use local or external data in the build script.

But I found something interesting,
If I deploy the app from “bad” PC to a good device (anything I have other than S4 and G3) then it works well,
so I ran and deploy from the bad PC to a “good” device and it’s OK,
then I uninstalled the app from G3 and manually copied and install the the last APK that the “bad” PC built into that G3, and it works OK!
Then I ran and deployed again to that same G3 from the same “bad” machine (now directly from Android studio and not manually) and again it doesn’t work well.

So when I run and deploy from “bad” PC to one of the weak devices (G3/S4) then I have the problem,
but if the same “bad” PC run and deploy the APK to other device first, and then I manually take that APK (without compiling again) then it works well.

(I guess that it I check that with systrace again maybe now the cores problem will be fine too)

Any idea how to proceed from here?


#12

Do you have Instant Run enabled? If so, disable it and see what your results are.


#13

Problem SOLVED after disabling instant run!

If I switch instant run on and off and run (without clean or changing anything) than the problem consistently come and go.

I found another way to make it work even with “Instant run” on, by going to:
Edit configurations -> app -> General -> Installation options -> Deploy
and change it from “Default APK” to “APK from app bundle”


#14

Glad to hear that you have things working!


#15

Thanks!
You helped me a lot!