Impact of using Multidex on app performance, stability, compatibility...? - android

The next version of my app has roughly 70K methods.
Knowing the exact implications of using Multidex (which usually means using the Multidex support library to support API<21) is important to me to make this decision:
Should I put a lot of effort (i.e. by fine tuning my Proguard configuration to shrink more aggressively, dumping some 3rd party libs etc.) to comply with the 64K methods limit, or should I just enable Multidex?
The documentation suggests that the Multidex support library may have some serious side effects (see Limitations of the multidex support library).
What should I really expect?
Failed installs on some devices?
Slow startup of the app (on 1st startup or always)?
New crashes or ANRs on some devices?
Overall performance degradation?
Feedback from your own migrations to Multidex would be greatly appreciated.

I'm not a specialist in Dalvik but I've worked on several projects that at some point required MultiDex and these are some of the lessons I learned:
Failed installs on some devices?
Some devices, specially old Gingerbread phones (but also ICS), use a very small LinearAlloc buffer which might cause errors while installing or cold-starting an app that has too many classes or whose class hierarchy is too complex. Enabling MultiDex doesn't contribute directly to this problem but allows developers to continue the "code bloat" up to the point where the app becomes too big to run on those devices... which sometimes only gets noticed when hundreds of very sad users start calling your customer support.
Slow startup of the app (on 1st startup or always)?
The first start after installing or upgrading is definitely slower, mainly due to the expensive I/O operations required to extract the secondary dex files from the APK into the file system. Subsequent starts are also affected proportionally to the size and complexity of classes that have to be loaded in order to bring up your first Activity, so it's good to keep the main components of the app (specially activities) in the primary dex to minimize startup time, although it's not always possible to do so.
New crashes or ANRs on some devices?
We've seen ANRs in Alcatel OneTouch (2.3.3) and Google Nexus One (2.3.6) phones that were caused by the dex extraction taking too long. In more modern devices, upgrading and cold starting multidex apps might take a bit longer but usually not long enough to cause ANRs.
Overall performance degradation?
Class loading becomes much slower and that affects the app in unpredictable ways. If you use a DI system, Protobuf or some other framework that generates hundreds of classes then you might find some of your application workflows becoming 20-25% slower after enabling multidex. One way to mitigate this is to load classes ahead of time via, for example, a background thread or a BroadcastReceiver but these, of course, will increate the memory footprint of the app and potentially slow down the device.
Also, some install-time dex optimizations might also be skipped if dexopts finds classes missing from the primary dex, so there might be a considerable penalty in terms of CPU and memory usage even if only a couple of classes end up in secondary dex files.
Should I put a lot of effort (i.e. by fine tuning my Proguard configuration to shrink more aggressively, dumping some 3rd party libs etc.) to comply with the 64K methods limit, or should I just enable Multidex?
MultiDex solves the 64K method limit but it's not a silver bullet and IMHO shouldn't be used as an excuse to avoid optimizing the size of the APK but if
You're only targeting modern devices (e.g. API 16+)
Performance/cold-start times are not critical
You have no time to optimize the app further
then MultiDex might be suitable, otherwise stripping unnecessary code is the way to go.

I ended up going with multidex, essentially because the roadmap of my app would have forced me to do so eventually (as I'm planning to integrate big libraries in a near future).
It's been more than a month and hundreds of thousands of installs/updates of the multidexed APK, so I can now say with decent confidence that the move to multidex did not have any significant side effect, in my specific case.
(note: the update only targetted API 11+, so I cannot speak of potential problems with Android 2.x).

Related

App performance issue or phone's performance issue

I work at a phone manufacturer (OEM).
One of our preloaded third-party apps has been complained about by our users that the performance is very bad on our mid-to-low end devices.
Without having access to the app's source code, how do I determine whether the performance problem is caused mostly by how the app was written or by the limitation of the device (e.g. CPU)?
This is an interesting question. Even though it should require code.
My take;
When it comes to performance especially when it comes to Android, the issue always has to do with application development.
If an application is struggling, regardless of its capabilities, it is trying to do too much at once. There are many ways to improve performance with asynchronous background threads, and with modern development Croutines.
People complain about performance for one reason. The application is showing the user it is struggling. If you are working on low end devices, your views should be very simple and clean, and data/views should be asynchronous to prevent too too much from happening at one time.

Do I need to code things differently for ART vs Dalvik?

I've been seeing reports (rumours) that soon Android will be switching from Dalvik to ART as it's default runtime. I have no real idea what that means, my guess the runtime is (kind of?) like the operation system.
My app doesn't do anything particularly special/unique in the sense of mostly it makes HTTP requests for data, and uses LocationListeners a few times.
On some articles I've read about the rumored change, I've seen some people saying things along the lines of "I like ART, I'd use it right now if X app supported it". (One app I remember being mentioned is Xposed)
I've switched my phone to ART, and my app seems to work fine, so I'm guessing the answer to the title question is no, but I'm curious as to how the Xposed app isn't compatible. What have they done (or not done) to make their app not work in ART?
ART is a different runtime for Android applications. All android apps run inside of a virtual machine, much like java code runs in the Java VM.
Classically, when you compiled an Android app, it would compile to Dalvik byte code, designed to run in the Dalvik runtime (virtual machine).
In Android Kitkat though, Google introduced a new experimental runtime called Android Runtime, or ART. This is a different virtual machine, a re-implementaton of the runtime for Android applications to help fix some of the fundamental flaws in the original design.
ART offers several advantages over Dalvik:
Ahead-of-time (AOT) compilation
Improved garbage collection
Development and debugging improvements
Support for sampling profiler
Support for more debugging features
Improved diagnostic detail in exceptions and crash reports
It should also help with things like the DEX limit.
As to your question, you do not need to do anything as a developer. Google has said plainly that "Dalvik must remain the default runtime or you risk breaking your Android implementations and third-party applications".
Google has announced at Google I/O 2014 that in the Android "L" release and beyond, that ART will replace Dalvik.
ART has now replaced Dalvik on the Nexus devices, and my six existing apps, available in the Google Store, all now fail to run. I see multiple lists of questions about ART causing app failures. I suspect the "new and improved" memory managment garbage-collection is the root cause of much of this. My Samsung devices did not have an option to select ART instead of Dalvik, so I am only now getting user reports of the failures under Android 5.x. It is reported that the implementation of the native interface is significantly less forgiving, and requires different and more explicitly defined global pointers, where previously local pointers would operate correctly. This means anyone using native code, and the JNI (native interface), may have to re-code their app, or target a different platform with a more stable system architecture.

Android apk compile to ART runtime and dalvik runtime

Google added a new ART runtime with Android 4.4. How can I target my apk to both ART runtime and Dalvik runtime?
This change is without consequences for the developers. Your app remains exactly the same, nothing to do there. Just make sure you target API 19 so that your app is available for KitKat users. They will decide in their phone if they want to use ART or Dalvik.
This is an old question now, but very key. I confirmed today, all my apps break with ART+Android-5 on Nexus-x tablets. ART does more strict JNI checks, so if your app uses java plus native code,the move from Dalvik to ART may break app operation. For me, it has been a complete show-stop. I have 6 apps in Google Store and all fail now on Nexus devices running Android 5.x, yet they run correctly on all 4.x.x (Kitkat) series devices. This is most frustrating. I am going thru all the ART/ Dalvik questions and answers on this site. ART and Android-5.x is very significant change, so the question asked here "How do I target my apk to both Dalvik and ART?" is a key and very critical question. Time has proven that the responses given suggesting "No difference to developers" is manifestly incorrect. It certainly is in our case.
Two specific issues are documented, and I quote from "Verifying App Behavior on the Android Runtime (ART)":
1) " Checking JNI code for garbage-collection issues
ART has a compacting garbage collector under development on the Android Open Source Project (AOSP). Once the compacting garbage collector is in use, objects may be moved in memory. If you use C/C++ code, do not perform operations that are incompatible with compacting GC. We have enhanced CheckJNI to identify some potential issues (as described in JNI Local Reference Changes in ICS)." In other words, the new ART memory mangement model may break your existing (and operational) native code.
2) " Error handling
ART's JNI throws errors in a number of cases where Dalvik didn’t.".
A limited explanation of some of the issues that will cause errors to be thrown by the Android 5.x ART is provided in: http://developer.android.com/guide/practices/verifying-apps-art.html#JNI_Issues
The forward-compatibility solution currently being adopted among users of Android devices running ART and 5.x, and facing non-operational apps, is a downgrade to Android 4.4.4, by unlocking the bootloader, wiping the device memory, and installing system image "Hammerhead", in the case of those running Nexus series tablets. For Samsung tablets, a tutorial is available at: http://forums.androidcentral.com/samsung-galaxy-s5/489071-tutorial-downgrade-samsung-galaxy-s5-5-0-4-4-kitkat.html
The dalvik or ART is only the runtime in the Android. As an app developer, you don't have to care about these differences. All you have to care about is your app's API level which is describing the dependence of the Android OS version.
And in Android 4.4, ART is only a development which is NOT the default runtime even if the release note describing that ART will make app use less memory and run quickly. If you want to find the different, you can wait for the next version of Android. In the opensource, I found the ART has been setting the default runtime selection.
For most apps ART will work just fine.
It is, however, not 100% compatible as something that work on Dalvik may not work on ART
Please visit this link for more information.

Stress Testing Android Dalvik [duplicate]

This question already has answers here:
Stresstest Memory on Android
(2 answers)
Closed 3 years ago.
I've been reading up on the Android dalvik, and I was curious as to how one would go about stress testing the Dalvik to evaluate its stability. I understand the Dalvik is meant for memory an processor constrained devices. So would allocating a lot of memory/increasing frequency of some CPU cores and then launching multiple applications be a way to test the stability?
I also understand that each independent process gets itsown instance of the Dalvik. So another possibility to stress the Dalvik would be to launch multiple applications that share a single process and a single instance of the Dalvik and see how stable the Dalvik is.
I would like to to know if either of these are good ways to measure the stability of the Dalvik. If both of them are good ways, which one would be a better test?
Thanks!
It's difficult to stress every part of a VM all at once.
You can write memory stress tests that exercise the heap and the garbage collector, synchronization stress tests (like the JSR-166 java.util.concurrent test suite), CPU stress tests that do lots of integer and floating-point computations on different cores simultaneously. And so on.
The trick is to write a test that does what you think it does -- a surprising number of "multi-core" tests end up single-threaded because of unexpected dependencies -- and whose results can be evaluated for correctness. A test that successfully causes instability isn't useful unless that fact is communicated to the user in some way. Making the VM crash is a pretty good way. :-)
Running multiple apps and services in the same process is theoretically possible but rare in practice. I don't think you'd actually be able to stress the system out any better this way, since only one app is in the foreground at a time, and if you're making requests of a service one thread will wait for the response while the other runs. You're better off just have one app with multiple threads, so you can control exactly what each does and how they interact.
Before you can do any of this, you need to define the scope of "stability". Simply running many apps isn't going to turn up anything, since there are hundreds of millions of devices running billions of instances of Dalvik with essentially no failures due to the VM itself (but any number due to bugs in apps, the framework, 3rd-party libraries, etc). Dalvik hasn't changed much since Android 4.0 (Ice Cream Sandwich) shipped two years back.

Should I build my Android app for x86?

I am developing an Android game, which I will upload to the market. I am using the NDK; the majority of the game code is C++.
Should I worry about supporting x86 devices? Are there actually any out there?
Currently I am building for ARMv6 only; building for both ARMv6 and v7 increases the APK size without making it any faster (it's already fast enough). It would be nice if I only needed to build for a single architecture.
If you can do it without too much hassle, I would do it.
Not because there are tons of Android/x86 devices, but simply because supporting multiple architectures is a fantastic way to shake out bugs that you might otherwise never encounter (or that would lie dormant until something changes on the system two years from now, and suddenly your app doesn't work anymore). It will make you a better programmer.
Also, I'm surprised that building for armv7 doesn't confer any advantage. Do you mean that you're already framerate-capped running the armv6 build on an armv7 device? If so, building armv7 may still allow your code to run faster, which typically saves energy even if it doesn't increase "performance". Less energy = people use your app longer.
Now, all that said, I don't know the Android toolkit, so I don't know how much hassle is actually involved with supporting multiple arches. If it's a major hassle, then by all means stick to armv6; it's a good baseline for "most" devices out there.

Categories

Resources