Well come on, I use it a lot Native Development Kit - NDK, we can say that the JAVA
allows you to write or re-use codes C
or C++
, but how it really works ?
Imagine calling any function written in C
within its application java
, this is a hand in the wheel for N reasons, you can gain performance, you can use codes or libraries written in C/C++, or simply make it difficult for someone to see your code, remembering that this is not something exclusive to java
, other languages also have this ability, for this to be possible it is necessary to have an interface that communicates between your code C
and the java
, this is where the JNI - Java Native Interface he will be responsible for linking your functions, at this point you will create functions in Java
calling the Functions of your native code...
Answering your questions one by one:
When we compile it becomes a real executable or it is
converted to "Java machine" (I don’t know if this is the way
correct to refer to)?
A: When you build a java application that makes use of a C/C++ code, at the exact moment of compilation when generating your own .apk
you will be creating a shared object
the famous .so
quite common when you want to share functions among other programs in C
, is not an executable, in which case you will be creating a shared library that will later be called by your java code (System.loadLibrary)
.
If it is a "java machine" independent application then this
means that the native features of the apps are
independent of Java now?
A: Yes it is independent, if when compiling you set the architecture x86
for example, then you can just copy this .so
for a PC and call any existing function from any other language reading that library, remember, what makes you communicate with your C application in JAVA is the JNI
...
From which API can I use NDK?
R: API 3
, that is has support from the Android 1.5
How will this treat the difference between ARM and Intel x86 processors?
The applications will be compiled at the time of installation on
device?
A: You define which architectures and NDK will create during your build .apk
, at this time your java application will contain all .so's
ie one for each architecture defined by you, they will be embedded inside your apk in the folder lib
, see an example of my . apk, I set it to be created for all architectures, see:
Inside every folder of this one .so
specific to each architecture:
The moment you run this application on android
it will identify which architecture is used and will load the .so
in the corresponding folder.
EDIT
I would like to make a few more considerations, the method shown above uses shared library include $(BUILD_SHARED_LIBRARY)
, this parameter must be defined within Android.mk
There is how to create a executável
, for such you must replace your Android.mk
for include $(BUILD_EXECUTABLE)
, works in a similar way, only in this case when compiling your app, new folders are created containing an executable binary for each architecture compiled by NDK
, but now you will have to treat the architectures within your code to find the file/folder correctly, as an example, I use something like this:
private String getCFileName(CPUArchitecture architecture){
final String CFileName;
switch (architecture){
case X86:
String CFileName = "x86_ederwander";
break;
case ARMEABI_V7A:
CFileName = "armeabi-v7a_ederwander";
break;
case ARMEABI_V7A_NEON:
CFileName = "armeabi-v7a-neon_ederwander";
break;
default:
CFileName = null;
String message= "Could not determine your processor architecture correctly";
Log.e(TAG,message);
throw new Error(message);
}
return CFileName;
At the time of running your apk it will define which binary with correct architecture to use, with the correct selection of the file you can run it, if you have any argument you can pass as parameter too, usually use something like this:
int executeCommandLine(String commandLine)
{
try {
Process process = Runtime.getRuntime().exec(commandLine);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuffer output = new StringBuffer();
char[] buffer = new char[4096];
int read;
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
Log.d("executeCommandLine", output.toString());
return process.exitValue();
} catch (IOException e) {
throw new RuntimeException("Unable to execute '"+commandLine+"'", e);
} catch (InterruptedException e) {
throw new RuntimeException("Unable to execute '"+commandLine+"'", e);
}
Each case is a case, there are pros and cons, I don’t really like to create binaries, it’s a gigantic job, you have to worry about finding the right architecture, you have to build a function in your java code to copy these binaries to a folder within your apk that is allowed to run this binary, but as I said everything depends on your project, in some cases you will not have a choice and create a binary will be the alternative, remembering that the compiled binaries, if you have compiled some for architecture x86
for example, if you copy this binary to a linux-x86
, you will literally run/run with a ./bincompilado-via-NDK
, so in this case you will no longer need the JNI
, there is no more interface, you are actually calling a compiled binary code...
From experience I assure you that the development and many of the Apps we know today for Android would not be much without the existence of NDK
, of course it is not something trivial and so we only use it when it is really necessary, usually in specific cases, you will not need it if you are creating something that does not require full processing power, but its existence opened the door for many applications to gain the performance of a native code, today with the constant evolution of processors ARM
gaining more and more processing power, we have on our phones a range of APP’s doing amazing things in real time, no bottlenecks, no latencies, I work with audio processing, my apps need extreme processing, something that Java cannot supply, the same happens for real-time image processing and games, these applications would not be the same if everything were written only in java, we would certainly suffer to make java realize or we would have to be light years ahead in architecture ARM
...
Guilherme: I temporarily withheld the answer because I found 2 google documentations that answered your question in different ways. I will search little more and ask on the google forum by which we should base.
– Carlos Bridi