Hacker News new | ask | show | jobs
by fidotron 4532 days ago
This is certainly good for games and similar multimedia heavy type apps.

However, if you're using C++ for portability for any sort of non-realtime needs you've lost your marbles, and would be better off with JavaScript (no, really) and/or platform specific code to leverage the class libraries of the respective platforms. C++ heavy apps on Android are larger, use more memory, and load less quickly. This isn't obvious if you're used to other worlds, but it is a side effect of how pervasive Dalvik is on the system. Even if most of your app code is in C++ it's still easy to get screwed by a GC pause caused by where you have to interface with the framework.

Much of the underlying problem here is that speed-wise Dalvik just isn't very good. It wasn't even competitive with J2ME VM performance when it first appeared, and took a long time to get close.

With all that said, native debugging has been a sore point forever, and any improvement in that area is welcome.

4 comments

If by JavaScript you mean making a webview-based app with something like Cordova/PhoneGap, then that's not a great option either. Pre-4.4 WebView on android is notoriously bad, and things as trivial as smooth scrolling are a huge issue. The same app performs fine on iOS and on Android 4.4 which uses Chrome's engine, but unfortunately it will be a while before older versions go the way of IE6. I agree that C++ is not a solution for portable GUI apps either (although it works great for portable games since OpenGL ES runs on pretty much everything.)
https://crosswalk-project.org/ is a Chromium-based runtime that works on Android 4.0+
> if you're using C++ for portability for any sort of non-realtime needs you've lost your marbles

Maybe if you're starting from absolutely nothing. If I had non-trivial functionality already written in native code then I suspect I'd rather write JNI bindings than do a complete rewrite in Java.

I'm also skeptical of 'use more memory' and 'load less quickly'. Even the GNU C++ standard library on an x86-64 desktop is a less than a megabyte. I can't imagine that being significant in either of those problem areas.

You're making the precise mistake we're talking about: don't project from your experience of desktop Linux to Android. This equally applies for any Java platform too as the VM performance characteristics don't resemble any from the Sun/Oracle family.

The key thing is to understand what is involved to get an Android app to start up. This is terrifying when considering just the Dalvik case, but what most C++ types don't realise is that even if your app is using NativeActivity it means you are really subclassing this: https://github.com/android/platform_frameworks_base/blob/mas...

This means in order to load the native lib you first have to load Dalvik, a whole load of classes relevant to the app, allocate the whole Dalvik heap for the app, and then you rely on the Dalvik code to initiate loading of the native lib. As a result this only becomes worth doing if the gains you're going to make exceed those losses, but I find it's quite common for people to ignore the downside, as a few comments here indicate.

Storage to RAM bandwidth on these things is not exactly stellar, so as a consequence loading takes a while. To make things worse if you want to deploy all supported native architectures you're multiplying the native code size by four, since you will want two ARM builds (v5 and v7), one MIPS, and an x86. As a consequence I'm unaware of anyone that habitually includes all of them, and just putting ARMv7 libs in is the norm.

The Google Play store will accept multiple build types and will deliver the correct builds to the correct phones automatically, no need for a fat binary.

While NativeActivity is interesting, for LOB apps we're much more likely to stick to native Android UI components, which means Android/Java activities. However, Loaders might then in turn use JNI as a model layer. I'm still working out the details myself, but I feel there should be a way for shared, cross-platform C or C++ code even if it relies on platform-specific UI and localization. The alternative, rather than JS, is probably Java2objc, used by Google for new developments.

Or Qt, as they support Android and iOS since version 5.2.

If you are doing commercial software, the licenses should be ok, but I am no longer sure how much.

Digia adopted the typical enterprise way of having sales people talk to you for price information.

The load time and memory consumption of a minimalist NativeActivity is so minuscule that it isn't worth discussion. Your argument beyond there seems to be of the good investment after bad variety -- that if you've made a marginal bad investment, you'd better keep making it just because. That is not good advice in any endeavor.

No one in this thread "ignore the downsides", and your point seems actually very undeveloped: After you've paid that unavoidable, very small initial price (that of course a fully managed app pays as well), you then have 100% minimal native app, using that legacy or cross platform code at full, 100% native speed, with no GC taxes, etc. There is no magical overhead just because you originally started with a native activity.

This is certainly not to say that native is the way to go, because if you're going to make heavy use of the Android API outside of the pure native elements like OpenGL, you're going to just cause yourself a lot of hassle, but most of the anti-native argument seems to derive from nothing at all.

And the ARMv7/v5/MIPS/x86 thing is just strange. Yes, it might be a consideration in some cases (although if it matters 9 times out of 10 you can set a flag and there you go), it is quite a departure from the claims about C++.

C++ heavy apps on Android are larger, use more memory, and load less quickly. This isn't obvious if you're used to other worlds, but it is a side effect of how pervasive Dalvik is on the system.

Citation required, as this is entirely the opposite of every experience I've had actually building apps that use significant native code. What are you basing this claim on?

There really isn't anything magical about Dalvik (or ART) -- it is a per instance runtime. C++ code doesn't suddenly become heavier or slower to load because of Dalvik.

And of course the overwhelming majority of games are mostly built using the NDK.

It's my understanding that this counter-intuitive performance problem with Dalvik is what crippled the original UI for Android Firefox - they were using their native C++ UI stack (the one used on Windows, Mac and Linux) to implement the whole browser UI, but they found that in practice a UI stack written in Java running on Dalvik performed better because it wasn't subject to all the weird performance penalties from interacting with android frameworks.
I don't think that's entirely correct (yes, XKCD #386 applies):

First, I'd hesitate to use the phrase "native C++ UI stack". Mozilla's UI framework is XUL, which is a mixture of JS and XML. Presumably there's C++ underneath, but based on my reading it's a mixture of web-based technologies.

Second, because the original Firefox for Android UI was written in XUL, they had to load the entire Gecko architecture in order to render any UI. That was ultimately the performance issue, not "interacting with android frameworks".

Because of that, the goal of the rewrite was to be able to show the UI immediately, while loading the Gecko stack in the background.

There's some good info on this at http://starkravingfinkle.org/blog/2011/11/firefox-for-androi... and http://www.mozilla.jp/static/docs/events/vision/2012/04-mark... .

This is intriguing - I had no idea that the Mozilla experience so closely mirrored my own.

The fun thing about Android is you can often spot when apps load the native code library since it generally leads to mysterious black screens during the loading of activities for exactly the kind of reasons mentioned there.

I would point out to all the above commenters, that Chrome is still largely native code, with simple wrappers on iOS and Android. http://www.chromium.org/developers/design-documents/android-...
Yes, but this also goes some way to explaining my assertion that such apps are disproportionately large and slow to start - Chrome exhibits exactly that behaviour.

When they get closer to having the OS WebView actually updated via Chrome channels then it's conceivable that the apparent startup time will come down, and it wouldn't surprise me if this is one of the main reasons for it.

If you see this recent thread: https://groups.google.com/a/chromium.org/forum/#!topic/blink...

They even say this: "The web is quite far behind in mobile, which is why we're applying a greater amount of focus to solving the problems we have on mobile, even at the expense of nice-to-have features."

This is quite an admission, and at odds with a lot of their noise. It's also telling about their problems because Chrome suffers from a sort of death by a thousand cuts. On mobile to get the user experience people demand (they aren't wrong to be after 60fps performance as studies have shown mobile users are even pickier than desktop net users) you simply can't afford things like that anywhere, let alone right as the app starts up.

You seem to think that each of these posts is supporting what you claim, when it's doing nothing of the sort.

Firefox was slow because it had a very expensive abstraction layer that, while tolerable on a high power desktop, was just too much for what could be a low power mobile device. They didn't switch from C++ to Dalvik, they changed their GUI layers and how they initialize. This does nothing, at all, to support your claim about native apps being either slow to start or being large.

Nor does the Chrome bit. It's a large, full-featured browser. Further, on what is it slow to start?