What is Android NDK?

From what I understand Android NDK is geared towards development with c or C++, despite supporting Java through the JNI (Java Native Interface) , however I would like to understand a few things:

  • When we compile it becomes an executable actually or it is converted to for "Java machine" (I don't know if this is the correct way to refer)?

  • If it is an independent application of the " machine java " so does this mean that the native features of the applications are independent of Java now?

  • From what API can I use NDK?

  • How will this address the difference between ARM and Intel x86 processors? Will the apps be compiled at the time of installation on the device?

Author: Guilherme Nascimento, 2016-11-08

2 answers

Well come on, I use the Native Development Kit-NDK, we can say that JAVA allows you to write or re-use C or C++ codes, but how does this really work ?

Imagine calling any function written in C within your application java, this is a hand in the wheel for N reasons, you can gain performance, you can use code 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 you must have an interface that makes the communication between your code C and java, it is at this point that enters the JNI - Java native Interface it will be responsible for linking its 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 an executable really or it is converted to to "Java machine" (I don't know if this is the way correct to refer)?

A: when you compile a java application that makes use of a C/C++ code, at the exact time of compilation when generating your .apk you will be creating a shared object the famous .so quite common when you want to share functions among other programs in C, it is not an executable, in this case you will be shared library that will later be called by your java (System.loadLibrary) code.

If it is an independent application of the "java machine" then this it means that the native features of the applications are independent of Java now?

A: Yes it is independent, if when compiling you set the architecture x86 for example, then you can simply copy that .so to a PC and call any existing function from any other language that reads this library, remember, what makes you communicate with your C application in JAVA is JNI...

From which API can I use NDK?

R: API 3, i.e. has support since Android 1.5

How will this address the difference between Arm and Intel x86 processors? The applications will be compiled at the time of installation in the device?

A: you define what the architectures will be and the NDK will create while compiling your .apk, at this point your java application will contain all .so's i.e. one for each architecture defined by you, they will be embedded within your apk in the lib folder, see an example of mine .apk, I set it to be created for all architectures, see:

insert the description of the image here

Inside each folder there will be a specific .so for each architecture:

insert the description of the image here

At the time you running this application in android it will identify which architecture is used and will load .so into 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 should be set within Android.mk

There is how to create a executável, for this you must replace your Android.mk to include $(BUILD_EXECUTABLE), it works in a similar way, only in this case to compile your app, new folders are created containing an executable binary referring to 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 execution of your apk it will define which binary with correct architecture to use, with the correct selection of the file you can execute it, if it has any argument you can pass as parameter also, I 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 creating binaries, it gives 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 inside your apk that has permission to run this binary, but as I said it all depends on your project, in some cases you will not have choice and create a binary it will be the alternative, remembering that compiled binaries, if you have compiled some for architecture x86 for example, if you copy that 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 interface anymore, 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 thing without the existence of NDK, of course it is not something trivial and so we only use when it is really necessary, usually in specific cases, you will not need it if it is to create something that does not require total processing power, but its existence opened the doors for several 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 in our phones a range of App's doing amazing things in real time, no bottlenecks, no latencies, I work with audio processing, my applications need extreme processing, something that Java does not account to supply, the same happens for real-time image processing and games, these applications would not be the same if everything was written only in java, surely we would suffer to make java account or we would have to be light years ahead in architecture ARM...

 27
Author: ederwander, 2017-06-05 15:29:06

Android NDK is a set of tools that allows you to implement parts of the application using native code languages such as C and C ++. For certain types of applications this can help you reuse code libraries written in these languages. That is, we do not need to reinvent the wheel if there are already good libraries in C or C++.

Example : we have been using Android NDK a lot to integrate FFmpeg into a project of audio and video player and live streaming for Android.

Libraries written in C or C++ are natively compiled for use through Java invocations. You can use Android NDK in any class in your project, through the native android APIs.

Yes, the files are compiled at the time of application installation. But after already compiled they will be accessible quickly.

To give you more details on how to use the Android NDK we would need to know more about your specific project. So feel free to post some code or ask more specific questions, and so we can help you in a more specific way.

 10
Author: neowinston, 2016-11-13 13:20:12