To develop applications on the Android platform, the common language is Java, and for projects, products that migrate from other platforms to Android, or developers who are accustomed to C + + programming, will want to reuse existing C + + code. The Android platform provides a way to reuse Native code, as well as an environment and toolchain for compiling C code: the NDK. The NDK is a chain of tools that makes it possible to use C language on Android. In fact, Android was originally on Linux put a Java environment, to say can not use C that is the unthinkable, but Google is not completely open only (say I am now in the belly black, for you can not let C programmers live on the Android more comfortable, is a man-made barriers).
There are two ways to take C code on a Android platform:
- Jni
- Native C executable Program
JNI mode
JNI was originally a Java provided by the framework of a reusable C code, Android has also made a number of extensions, adding a aidl used in the service framework, a set of tools, in the use of android.mk compiled with the Aidl file can be automatically generated according to the corresponding Java code and compiled.
The main use of JNI is to compile C code into a dynamic library, which is called in Java. The steps to use are this:
- Declaring the native method in Java code
- In JNI (this part of the bridge C code called the JNI layer) layer implements the local method corresponding to the Java layer according to the naming convention
- Loading C dynamic Library in Java layer
Examples of JNI patterns, such as Qt on Android, Vitamio, and some examples of the Android framework itself, such as ServiceManager, Android.util.Log.
Native C executable Program
Android is Linux, and invoking the Native executable is a natural way. Java also provides language-level support, and the runtime.exec () function is doing this. With the exec () boot process, you can read the standard output of the Native process and write data to the standard input of the Native process.
An example of how native executable programs are invoked, Wifimanager communicates via the control Interface and Wpa_supplicant (wpa_suppliacant for wireless connections, native C-executable) when connecting to a wireless network, such as scanning access points, selecting networks, Connect to the network and other instructions.
Also, some Android system set-top box comes with a broadband dial-up (PPPoE) program, also C executable program, Java layer Pppoeservice finally by calling Pppd/ppppoe such programs to perform the actual dialing process.
Also, the root that we often say is actually implemented by invoking a program called Su.
We can use this in real-world development, for example, to see what files are in a directory, to call the LS command directly, and to read its standard output.
Java and C Program communication issues
When we call C code through Java on Android, we also encounter a problem with process or inter-thread communication.
This is specifically about the Java process and the C process, the Java process, and the C shared library communication issues.
Sometimes our requirements are simple, blocking calls C code, get the results of the calculation to achieve the goal. For example, you call a hash function of the C shared library through JNI, or you call a Native executable through runtime.exec () to calculate the hash read its standard output to get the result. These scenarios are simple enough that you don't have to think about the communication between Java and C shared libraries or C Native executables, but there is no state of affair to maintain anyway.
But there are some complex applications, and we have to build a long-term communication mechanism between Java and C.
Or the example of a wireless connection. Well, interested readers can browse the source code of Wpa_supplicant, which provides a control interface based on the Dbus, UNIX domain socket two way.
In fact, the common inter-process communication mechanism of Linux, such as pipeline pipe, socket, signal, can also be used for Java layer and C layer of communication, and the Android framework is so used. For example, we are very familiar with the first process of Android World Zygote (actually app_process, renamed to Zygote after startup), there is a function to start the Java process, when we want to launch an APK, the APK process is finally started by Zygote (You can share Java class libraries, C shared libraries between processes, greatly conserve resources and speed up the process startup process), and Zygote is the socket that accepts commands.
Another example of the signal, we see a lot of process management class application, actually use android.os.Process to kill the process, and Process.kill (), is actually to send a signal to the target process, very standard Linux mechanism.
There is also a common mechanism for inter-process communication between Java and C Native executables: standard input and output. We can write data to the standard input of a process, or it can read from its standard output. Then we can define a set of control protocols for communication.
Like pipe pipes, sockets can be used for interprocess communication (Java and C Native executables) or for in-process communication (Java and C shared libraries). So what are we going to do with the scenario? The previous Wireless Connection service program Wpa_supplicant can give us some hints.
If we implement a service with C, and the Java layer needs to access the service frequently and needs feedback, then we can do it.
Trying to say a scenario, we implemented a module with C that supports parallel download (single-threaded select model), and the Java layer frequently downloads images (Java layer on Android doesn't seem to have an easy-to-use, low-resource HTTP download library), such as a cloud album class application or video class application, We can delegate the download action to the C process.
interprocess communication, the Android framework also has a new framework that expands on the Linux IPC Framework Binder, many Native system services use binder frameworks, such as Audioflinger, which we call Audiomanager in the Java layer to set the volume function, it is the functionality of the Native system service Audioflinger that is used by the Binder framework, which is a typical cross-process call, but as a Java program, you don't have to care about this at all.
Readers who want to learn more about Binder can learn more. Here are the limitations of binder: Not all C programs can use binder to register services, only authorized services such as Media.player, Media.camera such as Native system services can, if you are system development, you can modify the authorization list ( Use UID control to allow your C program to register the service, and as an application developer, do not be paranoid, or consider using piping pipe, socket or standard input and output secure.
compiling C executable program
There are several ways to compile the C executable program for the Android platform:
- Using the NDK, use Android.mk
- Manual use of Precompiled GCC compilation
- Using Qt 5.2, refer to "Introduction to the development of Qt 5.2 for Android under Windows" and "Windows Qt for Android compiled Android C language executable program"
integrating and using C executable programs in APK
How do I integrate and use a C executable program in APK? Follow these steps:
- The executable can be placed in the assets directory, which will be packaged automatically when packaged as an APK.
- APK run-time access to resources within the Assets folder, release executables, add executable permissions
- Use Runtime.exec () to start an executable program
Android calls C program for seven meat of eight vegetarian