I have a question about the limitations of what you can do in native code on the Android platform.
Basically I have developed a library in native C code that uses UDP sockets for SIP/RTP and uses OpenAL for audio recording/playback - basically the whole application.
The idea is to have as much as possible in native C code rather than Java code. I want to do this because I am going to use it on other platforms as well.
My question then is simply - is it possible to just use the Java for the GUI and then all processing in native code?
What will happen when my native code tries to create a socket, bind it, record audio, play it, etc - since it is in native code, do I need to setup permissions for it (such as application accessing microphone and whatnot) or will it just bypass this stuff since its native code?
Can native code do pretty much anything it wants on Android like on PCs?
Sorry if its unclear; just tell and I'll try to improve it
Thanks
You can do pretty much anything you want in native code, but the only OS-level thing really supported is OpenGL, OpenSL, and some number-crunching libraries (compression, math, etc).
However, at any time you're free to use the JNI to call a Java method, so you could use the standard Android API for networking (classes like Socket, etc). Obviously, since the call is going through the Java API, all the normal Android permissions apply (like android.permission.INTERNET).
EDIT: As elaborated in the comments, the standard libraries that are part of the NDK do have support for sockets.
You still need your application to have permissions. For example, your native sockets will not work without android.permission.INTERNET in the manifest.
<manifest xlmns:android...>
...
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
Another option is to create the socket at the Java layer and pass it down. Here's an example of interacting with the socket in native land, see the method org_..._OpenSSLSocketImpl_connect():
http://www.netmite.com/android/mydroid/dalvik/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
The Native Android API is a nice article for NDK.
is it possible to just use the Java for the GUI and then all processing in native code?
Yes. And you need to set appropriate permissions to your AndroidManifest.
record audio, play it,
You need to use OpenSL ES API for recording and playing audio in the native side. It means your application should be for Android 2.3 or later.
Or, NVIDIA provides a framework that allow we to be able to develop using C++ for Android events, sensors, audio and so on even though for Android 2.2 or earlier.
Tegra Resources - Android SDK & NDK sample applications and documentation
You may like to check out csipsimple which is a example of using the pjsip sip library (which is written in C) in a java android application.
I haven't looked into how it does the sockets communication but it should give you a more complete example of what you are trying to do.
Related
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!
Can anyone please tell me how to add a C++ file in to an android project? Is there any method to import classes other than java classes?
The answer is that, you can't really add a C++ file directly to a project, but you can compile it and load it into the code that runs in your process and interface to it using the JNI. This is a way to interface native code to Java. However, be aware that you can't really do that much with the JNI. Getting access to standard Android things like UI, Intents, service connections, etc.., these are all somewhat more difficult to use in native code. And you certainly can't take a UNIX app "off the shelf" and stick it on Android by using the JNI. this is a fairly good looking tutorial on the JNI with Android. However, like I said, using the JNI is not an excuse for learning java and the Android SDK. The main reasons people use native code are for utility code (like crypto stuff) and performance (for example, quite a few Android games use the NDK)..
You have to use android NDK. Just download it and refer from android official site.
Is there anyway I could write 100% native C code for Android? I know there are ways to write some C code inside Java code, but I don't know any Java and I hate Java anyway.
Is there anyway I could write pure C code that will run under Android?
There is, as of Android 2.3: NativeActivity. But you don't get access to any of the niceties of Android's Java libraries; you're on your own in the wild west. This is really intended for people writing high-performance games.
Yes, there is support for writing completely native activities. You can check out the native-activity sample application.
I would not recommend this path, though, as in my experience applications that are heavy in NDK code are very difficult to debug. I would rate the Android native debugging experience as lacking.
Edit - one caveat is that you will still be doing plently of Java--just through the JNI.
Might be more trouble than it's worth, you could possibly write your logic in C code and import that to java using extern or external (I forget which now) and then do the GUI in java. There's really no point to using straight C in android unless you want to REALLY optimized your logic. Most of the calls you can make are wrapped anyways so you would have to make those calls to access certain things on an android device. Long story short : not a good idea unless you need faster logic.
You can write most of the application in C around a NativeActivity. However, some Android features can only be used from Java, so you'll need to use JNI instead of pure native. See the official overview.
Not really an immediate source code question per se....but Im looking into doing some casual Android Programming, nothing heavy.
But it seems to use alot of XML and Java......what I wonder though is why is it that android is written mostly in C and XML (along with C++ and Java) with it being closely related to the Linux OS......but why is the "main" language for programming in android Java?
Just out of curiosity of course.
The "main" language, as you called it, is Java. You can use C/C++ via the NDK, but you won't need it unless you are doing some special stuff. If you wonder when you would need to use C/C++, take a look at the official documentation:
When to Develop in Native Code
The NDK will not benefit most applications. As a developer, you need to balance its benefits against its drawbacks; notably, using native code does not result in an automatic performance increase, but always increases application complexity. In general, you should only use native code if it is essential to your application, not just because you prefer to program in C/C++.
Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on. Simply re-coding a method to run in C usually does not result in a large performance increase. When examining whether or not you should develop in native code, think about your requirements and see if the Android framework APIs provide the functionality that you need. The NDK can, however, can be an effective way to reuse a large corpus of existing C/C++ code.
The Android framework provides two ways to use native code:
Write your application using the Android framework and use JNI to access the APIs provided by the Android NDK. This technique allows you to take advantage of the convenience of the Android framework, but still allows you to write native code when necessary. You can install applications that use native code through the JNI on devices that run Android 1.5 or later.
Write a native activity, which allows you to implement the lifecycle callbacks in native code. The Android SDK provides the NativeActivity class, which is a convenience class that notifies your native code of any activity lifecycle callbacks (onCreate(), onPause(), onResume(), etc). You can implement the callbacks in your native code to handle these events when they occur. Applications that use native activities must be run on Android 2.3 (API Level 9) or
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.
I am just guessing but Java is a bit easier to program than C/C++ so its more attractive to new programmer which is also good for the platform success itself.
Another reason might be that an application written in java runs in a separate VM so it can be much easier controlled by android. If a vm is not responding the main OS can just kill it and the phone is still responding.
Suaron... From a stability point of view Java apps should be less likely to take down the device. So Java || C# || C++/CLI safer than C++ vs C vs Assembly. To this end the API is in Java and so most Apps are in Java.
On the other hand C/C++ gets closer to the hardware and is more appropriate for writing libraries that interact with hardware. It is much easier to shoot yourself in the foot with C++.
JAL
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?