I've been doing a fair amount of research, and have even experimented some with the NDK for Android (not so much the SDK). What I haven't been able to really find though is a clear and concise definition for what the NDK cannot do (besides lack of exception handling and rtti).
I've been mapping out some code for a game and a game engine for Android (Written entirely in the NDK) but it seems to not be as supported as many would like it to be. Not only that, but I'd like to be able to give my game a sexy U.I. without having to write everything from scratch in OpenGL.
While I'm sure it's easier in Java, I'd like to know if the NDK's front end/U.I. components are getting to a point to where they'd even be comparable with Java in terms of Touchscreen IO , Sound, and Graphical Interfaces. Worst case scenario I can write the U.I. in Java and just call native methods from that, but I'd like to be able to do more if possible.
Thanks.
Edit
If C++ is even somewhat on par with Java's U.I. feature set, it would be cool to know which of the two gives more control and customization. For example, while the Java implementation may be easier to use, does it give the programmer a lot of options to fine tune a "look" which resembles something specific?
Official NDK can do exceptions and rtti just fine. Read the "docs/CPLUSPLUS-SUPPORT.html" file distributed with Android NDK.
In C++ only thing you can not do is implement Java interface, inherit Java class and define new Java class. Otherwise - you can do everthing Java can. Only problem with that will be that a lot of things (like accessing Java object members, or calling Java functions) will require usage of JNI and that code will look really ugly. So if you need for UI creating/inheritance of Java classes, then you can code everything in C++.
I suggest to use JNI only for performance critical code. Mixing code - Java for UI, mathematical calculations in C/C++ is really easy.
Or if you code game by using OpenGL ES - that's also fine.
Related
So I am trying to make c++ apps in android, and with now good tutorials I can find how to start from the ground up, I decided to start by learning everything about android its self. This is a good explanation that I have found.
Let me know if this is correct.
So to make an app with c++ you need to use the ndk and jni to interface with java calls, and the native libraries in android were written in c/c++. SO to use the native c/c++ libraries you have to make calls to java in c++???
If you want to write everything in C/C++, use the NativeActivity
there is an official tutorial about this.
But, I don't think that's a good idea to write code in this way unless you are a game developer, and really fluent about everything about OpenGL. Becuase it is much convenient to write the UI part in OpenGL by pure C/C++.
And, in most common cases, we use part of our code by combine JNI and C/C++ to porting C/C++ dependencies to Java space.
Not to use native libraries. But yes, some functionality does require you to call back into Java. The Android framework is written in Java, and not all parts of it are exported to C.
Really I don't suggest writing an entire app in C or C++. I suggest writing only computationally heavy parts in C++, and doing the UI in Java calling down to C++ as needed. It just ends up cleaner that way. THe only time I'd consider writing the GUI in C++ would be if it was pure OpenGL.
Java GUI/system interface with C++ logic is fairly common- it allows you to write a common library between iOS/Android/desktop for the business logic and customize the UI to the platform.
For example, I want to create a simple application based on GPS, with making waypoints, showing them on map, etc.. So, is it possible to make such an app using C++ only, without any Java sources? Would it be more difficult than making the same on Java?
So, is it possible to make such an app using C++ only, without any
Java sources?
No. If you want to receive GPS coordinates, there is no way to do this without any Java code.
You could write an app in which Java is used as a thin wrapper around native code, using JNI to exchange data between Java and C++. However...
Would it be more difficult than making the same on Java?
Yes! In addition, the app would likely end up being:
Slower.
Buggier.
Harder to understand and maintain.
For Android development, Java is just the natural, normal, default language, and C++ is for exotic special tasks, typically those which involve really intensive calculations. You use it when you need it, not because you don't "want to" write in Java or because "Java is slow".
Writing correct JNI code is also not exactly trivial. For example, it's very easy to get local references and global references wrong if you don't read the documentation, as the compiler cannot detect their incorrect usage.
As the official documentation of the Android Native Development Kit says:
Before downloading the NDK, you should understand that the NDK will
not benefit most apps. As a developer, you need to balance its
benefits against its drawbacks. Notably, using native code on Android
generally does not result in a noticable performance improvement, but
it always increases your app complexity. In general, you should only
use the NDK if it is essential to your app—never because you simply
prefer to program in C/C++.
It also says:
You cannot access features such as Services and Content Providers
natively, so if you want to use them or any other framework API, you
can still write JNI code to do so.
Yes, search for Android NDK. Apparently it's a bit of a hassle, you'll be using SO a lot!
two years ago i developed an Augmented Reality framework on android-7 (Eclair). Since AR application are computationally intensive task, I developed a JNI c++ library used by a Java activity to render and register the virtual environment. The sensor readings acquired in Java are passed to the underline c++ library to compute the registration of the virtual environment. Tridimensional objects are rendered by a native draw function called from a GLSurfaceView. This results in a lot of JNI call.
Now I would like to port the application to android-15(Ice Cream Sandwich). Starting from android-9(Gingerbread) Android allows to use NativeActivity.
I would like to understand which is the better way to develop an AR application. Since every JNI calls introduce an overhead it would be much better to avoid them. Is it possible using NativeActivity? I didn't find an exaustive guide that explains how NativeActivity works but reading this document it seems that it results in a lot of JNI calls anyway. Is there any architectural document that explains how NativeActivity works? Is NativeActivity just a "JNI wrapper" to avoid java code? Concerning performances,are there any advantages using NativeActivity instead of a JNI library as I done before?
Thanks a lot.
NativeActivity will not give a performance boost to your framework. It still uses JNI to communicate with the System, only under the cover.
Moreover, there are good reasons not to use it. If I understand your purpose correctly, you want other applications to take advantage of your code. By forcing them to use NativeActivity you seriously reduce their freedom, and require that they struggle with a less familiar environment. There is a number of limitations with NativeActivity, e.g. it cannot load more than one JNI library.
Finally, I would suggest a completely different direction if you look for optimization of your AR framework: you can use the new setPreviewTexture() API.
As far as I understand it you still are bound to JNI also when using NativeActivity. This class can be used as starting point and encapsulates some functionalities for your convenience but the underlying technology to access native code has not changed and ist still JNI. So in my opinion you only can do some benchmarks to check if NativeActivity is more efficient for some reason (may be the guys at Google do know some hacks that make it faster than your solution).
I've worked with OpenCV in combination with Android before and what I always tried to do is to use as few calls as possible between my native code and my java code. When I look at the OpenCV port for Android though, it seems like they just create a wrapper function for every native function and call these from java. Now unless I totally misunderstand the principal of swig wrappers and the whole idea of this port, won't this be a lot slower than doing the actual coding in native code? I noticed that passing data between native code and java code is really slow, so I don't get why it seems to be the most normal thing in this port.
I did use it myself, but I just decided to ignore all the wrappers and use the code as it is and create my own wrapper using the normal way presented by Android tutorials.
So my question is, am I just wrong about the disadvantages? Or are they actually there and what is the real advantage of using OpenCV in this was? I know these questions are somewhat informal, but I hope you guys can help me out.
I can't give you the answer you're looking for, but here's what I think: there are many examples of JNI layers that wrap every native function - OpenGL, Android's Canvas, etc. Calling trough JNI is slower than working entirely in native code, but the question is does it make any difference for a concrete application? I believe in the majority of cases this time penalty is ignorable in comparison with the time spent inside the native functions. However I favor doing as much work as possible in native code for Android apps, not mainly because of the faster execution, but because Java is awkward language compared to C and C++.
The Android NDK has just been significantly expanded to include support for writing android applications entirely in native C/C++ code. One can now capture input events on the keyboard and touch screen using native code, and also implement the application lifecycle in C/C++ using the new NativeActivity class.
Given all the expanded native capabilities, would it be worthwhile to completely bypass Java and write Android application in native code?
The NDK is not native per-se. It is to a large extent a JNI wrapper around the Android SDK. Using NativeActivity gives you a convenient way of dealing with certain app-life cycle events, and add your own native code on top. ALooper, AInputQueue etc. are all JNI wrappers of the Java SDK counterparts, some with additional code that is private and unaccessible for real apps.
When it comes to Android development, there's no such thing as writing an application entirely in native C++ - you will (in every real App case that I can think of) always need to use the Android API:s, which are to a huge extent pure Java. Wether you use these through wrappers provided by the NDK or wrappers that you create yourself doesn't really change this.
So, to answer your question: No, it wouldn't be worthwhile, because you would end up writing JNI wrappers for SDK calls instead of writing JNI wrappers to your own Java methods that do the same thing, with less code, simpler code and faster code. For example, showing a dialog using "pure c++", involves quite many JNI calls. Just calling a Java method through JNI that does the same thing will give you faster code (one JNI call), and, arguably, code that is easier to maintain.
To fully understand what you can do, you really must examine the Android source code. Start with native_app_glue.c, which is available in the NDK, then continue with the OS implementation of AActivity, ALooper, AInputQueue etc. Google Code Search is a great help in this. :-)
If it is easy to do in Java, and includes many calls, call a method through JNI that does it all, rather than writing all the extra code to do it with multiple JNI calls. Preserve as much of your existing C++ code as is reasonable.
Not if you are just making a standard application. The Java SDK is more complete than its Native counterpart right now so you would still be making things more difficult for yourself.
If you are not doing something that requires the NDK (read: real time performance sensitive) then stick with Java.
Just some food for thought but if you have an app on iOS and Android, some C/C++ code might be shareable. Obviously the iOS Obj-C and platform specific code wouldn't work elsewhere. (Ditto for the Android specific stuff). But you might be able have some shared code that's platform neutral.
If you can, stick with the java style apps until versions of Android supporting native activities constitute a significant fraction of the installed base.
For things that were hard to do before - particularly ports of existing code - this will probably be a big help.
It's not entirely clear yet what has changed vs. just writing your own thin java wrapper. For example, is there still a copy of the dalvik VM hanging around?