Android NDK Development Tutorial _android

Source: Internet
Author: User

The Android NDK is preceded by the "native" word in the SDK, native Development Kit, which Google calls "NDK".

As we all know, the Android program runs in the Dalvik virtual machine, NDK allows users to perform part of the program using native code languages such as C + +.

The NDK includes:

The tools and build files needed to generate a native code base from C + +.

Embed a consistent native library in an application package file that can be deployed on an Android device (application packages files, that is, a. apk file).
Support for all future Android platforms some column native system header files and libraries

I. Background of the creation of NDK

Since its inception, the Android platform has supported C and C + + development. As we all know, the Android SDK is based on Java implementation, which means that third-party applications that are developed based on the Android SDK must use the Java language. But this is not equivalent to "Third-party applications can only use Java." When the Android SDK was first released, Google claimed that its virtual machine Dalvik supported JNI programming, where third-party apps could invoke their own C-dynamic libraries through JNI, meaning that the "java+c" programming approach was always achievable on the Android platform.

However, Google also said that the use of Native SDK programming compared to the Dalvik virtual machine also has some disadvantages, the Android SDK documentation, can not find any help in JNI. Even if third party application developers use JNI to complete their own C Dynamic link library (so) development, how so how to package with the application to apk and publish? There are also technical hurdles. For instance, the program is more complex, the compatibility is difficult to guarantee, cannot access the framework api,debug more difficult and so on. Developers need to use them at their own discretion.

So Ndk was born. NDK full name is native Development Kit.

NDK release, so that "java+c" the development of the way to finally become a positive, the official support of the development of the way. NDK will be the beginning of the Android platform to support c development.

Second, why use NDK

1. Protection of code. Because the Java layer Code of APK is very easy to decompile, but the C + + library Reverse sink is very difficult.

2. The existing open Source library can be easily used. Most of the existing open source libraries are written in C + + code.

3. Improve the efficiency of the implementation of the procedure. High-performance application logic will be required to use C development, thereby increasing the execution efficiency of the application.

4. Easy to transplant. The library can be used in other embedded platforms easily.

Iii. NDK Introduction

1.NDK is a collection of a series of tools

NDK provides a range of tools to help developers quickly develop a C (or C + +) dynamic library and automatically package so and Java applications as APK. The tools that help developers are huge.

NDK integrates the crossover compiler and provides the corresponding MK file isolation CPU, platform, ABI, and so on, the developer simply modifies the Mk file (indicating "which files need to compile", "Compile attribute Requirements", etc.) to create the so.

NDK can automatically package the so and Java applications, greatly reducing the developer's packaging work.

2.NDK provides a stable, limited-functionality API header file Declaration

Google explicitly declares that the API is stable and supports the current published API in all subsequent releases. As you can see from this version of NDK, these APIs support a very limited number of functions, including the C standard library (LIBC), the standard math Library (LIBM), the compression library (LIBZ), and the log library (Liblog).

Iv. Building of NDK development environment

1. Download and install Android NDK

Address: http://developer.android.com/sdk/ndk/index.html

2. Download and install Cygwin

Since NDK must use make and GCC when compiling code, you must first build a Linux environment, Cygwin is a UNIX simulation environment running on the Windows platform, for learning unix/linux operating environment, or porting applications from UNIX to Windows, which is very useful. With it, you can use NDK to compile C and C + + code without installing Linux. Download Address: http://www.cygwin.com

1 and then double-click to run it, after running you will see the Installation wizard interface.

2 Click Next, at this time let you choose the installation mode:

Install from Internet: Download directly from the Internet and install immediately (after the installation completes, the downloaded installation files are not deleted, but are still reserved for next installation).
Download without installing: Simply download the installation file to the local, but temporarily not install.
Install from local directory: Do not download the installation files and install them directly from a directory containing the installation files.
3 Select the first item and click Next.

4 Select the directory to install, note that it is best not to put in a directory with Chinese and space, it seems to cause installation problems, other options do not change, then point next:

5 The previous step is to choose to install Cygwin directory, this is the selection of the installation package you download the directory, the default is the directory you run Setup.exe, direct point next can be:

6 At this time you have a total of three connection options:

Direct Connection: Directly connected.
Use IE5 settings: Connect using IE's connection parameter setting.
Use HTTP/FTP proxy: Connect using an HTTP or FTP proxy server (you need to enter a server address, port number).
Users can choose according to the fact of their network connection, under normal circumstances, all choose the first, that is, direct connection mode. Then click "Next".

7 This is the selection of the site to download, select the next point.

8 Download the loading installation package list at this time

9 Search is you can enter the name of the package you want to download, can quickly filter out the package you want to download. The four radio buttons are the style of selecting the bottom tree, and the default is OK, don't move. View default is category, the proposed change to full display all the package to check, the province of some bags are hidden away. The bottom left corner of the check box is whether to hide expired packets, the default hook, do not worry about it, the bottom of the download we want to install the package bar, in order to avoid all downloads, here are listed behind the development of NDK to use the package: autoconf2.1, automake1.10, Binutils, Gcc-core, gcc-g++, Gcc4-core, gcc4-g++, GDB, Pcre, Pcre-devel, gawk, make a total of 12 packages

10 and then start to choose to install these packages, point skip, turn it into a digital version format, to ensure that the bin item into a fork, and SRC is the source code, this is not necessary to choose.

11 below test the Cygwin is not already installed.

Run Cygwin, in the pop-up command line window input: Cygcheck-c Cygwin command, will print out the current Cygwin version and running state, if the status is OK, then Cygwin run normal.

Then enter gcc–version,g++--version,make–version,gdb–version to test, if all print out version information and some description information, then Cygwin installation success!

3. Configure NDK Environment variables

A First find the Cygwin installation directory, find a home\< your username >\.bash_profile file, my is: E:\cygwin\home\Administrator\.bash_profile, ( Note: I installed my home folder under Nothing, the solution: first open the environment variables, the inside of the user variables in the home variable deleted, in the E:\cygwin\home folder to create a folder named Administrator (is the user name), and then the E:\cygwin\etc\skel\.bash_profile copy to this folder).

b Open the Bash_profile file and add ndk=/cygdrive/< your letter >/<android NDK directory > For example:

Ndk=/cygdrive/e/android-ndk-r5

Export NDK

NDK This name is random, for the sake of later use convenient, choose a short name, and then save

C Turn on the Cygwin, enter the CD $NDK, and if you output the/CYGDRIVE/E/ANDROID-NDK-R5 information configured above, the environment variable setting is successful.

4. Use NDK to compile the program

A Now we use the installed NDK to compile a simple program, we choose NDK Example Hello-jni, my location in E:\android-ndk-r5\samples\hello-jni (depending on your specific installation position),

b Run Cygwin, enter the command Cd/cygdrive/e/android-ndk-r5/samples/hello-jni, and enter the E:\android-ndk-r5\samples\hello-jni directory.

C Input $NDK/ndk-build, after successful execution, it will automatically generate a libs directory, the compiled generated. so file. ($NDK is to invoke the environment variable that we have configured before, Ndk-build is the compiler that invokes NDK)

D At this point to the Hello-jni Libs directory to see if there are generated. so file, if there is, your NDK is running normally!

5. Integrating the C + + development environment in eclipse

A  Install Eclipse's C + + Environment plug-in: CDT, here is the online installation option. First sign in to http://www.eclipse.org/cdt/downloads.php and find the online installation address for your Eclipse version of the CDT plugin.

b Then click the Help menu to find the Install New Software menu

C Click the Add button, fill in the address, come out of the plugin list, select All, and then choose Next to complete the installation.

D When the installation is complete, right-click a new item in Eclispe, and if a C + + project appears, your CDT plugin is successfully installed!

6. Configure the C + + compiler

A Open Eclipse, import NDK's own Hello-jni example, right-click the project name, click Properties, eject the configuration interface, then click Builders, pop up the list of compiler tools for the project, then click New to add a compiler, Click on the Add interface, select Program, click OK.

b There is a add interface, first to the compiler configuration name, such as: C_builder, set Location for < you cygwin installation path >\bin\bash.exe procedures, example: E:\cygwin\bin\bash.exe, Set working directory for < Your cygwin installation path >\bin directory, for example: E:\cygwin\bin, set Arguments as--login-c "cd/cygdrive/e/android-ndk- R5/samples/hello-jni && $NDK/ndk-build "

In the configuration above,/cygdrive/e/android-ndk-r5/samples/hello-jni is the directory of the program you are currently compiling, $NDK is the previously configured NDK environment variable, the two are configured according to your specific installation directory, and the rest is not changed. Arguments This string of parameters is actually to the Bash.exe command-line program to pass parameters, into the directory to compile the program, and then run the Ndk-build compiler program

C Then switch to the Refresh tab and hook up to the refresh resources upon completion

D Then switch to the Build Options tab and tick the last three items

E Then click on the Specify Resources button, select the Resource directory, check your project directory can

F Finally click Finish, click OK to save the configuration just now, note: If you configure the compiler under other compilers, remember certain points up button, put it to the first place, otherwise C code compilation later than the Java code, will cause your C The code must be compiled two times to see the latest changes.

G The compilation configuration is complete, now to test if it can be compiled automatically, open the project JNI directory of the Hello-jni.c file to the hint Hello from jni! Change to another text: Hello, my name is Alex. , and then run your program in the simulator, if the simulator shows you the latest modified text, then congratulations! You have all been configured successfully!

V. Develop your own NDK program

The best way to get started is to learn the example of Android, which is achieved by learning the Android NDK demo program: Hello-jni.

1, the development of the environment to build

1 Android NDK development needs to be done under Linux: because you need to generate a. So file that can be run on arm, you need to use a cross compilation environment, and cross-compilation needs to be done under Linux.

2 Install the ANDROID-NDK development package, this development package can be downloaded on Google Android website: The tool of the development kit can be compiled into a library of Android JNI/C + + code

3 Android Application development environment: includes Eclipse, Java, Android SDK, ADT, etc.

How to download and install ANDROID-NDK I am not verbose here, after installation, you need to add ANDROID-NDK road strength to the environment variable path:

sudo gedit/etc/environment

Add your ANDROID-NDK installation path to the environment PATH environment variable, and then let the changed environment variable take effect immediately:

Source/etc/environment

After the above steps, knock at the command line:

Ndk-bulid

The following error, rather than the Ndk-build not found, indicates that the NDK environment has been successfully installed.

Android ndk:could not find application project directory!
Android ndk:please define the Ndk_project_path variable to it.
/HOME/BRAINCOL/WORKSPACE/ANDROID/ANDROID-NDK-R5/BUILD/CORE/BUILD-LOCAL.MK:85: * * * Android ndk:aborting. Stop.

2. Code writing

1 The first is to write Java code

Build an Android application engineering Hellojni to create a Hellojni.java file:

Hellojni.java:

Import android.app.Activity;
Import Android.widget.TextView;
Import Android.os.Bundle;
The public class Hellojni extends activity
{/** called the ' when ' is the ' The activity ' is a
  -a-created
  c void OnCreate (Bundle savedinstancestate)
  {
    super.oncreate (savedinstancestate);
    TextView TV = new TextView (this);
    Tv.settext (Stringfromjni ());
    Setcontentview (TV);
  }
  /* A native method, which is implemented by the ' hello-jni ' native library, which was packaged with this application. *
  /public native String Stringfromjni ();
  Public native String Unimplementedstringfromjni ();
  /* This are used to load the ' Hello-jni ' Library on application startup. The library has already been unpacked into
   /data/data/com.example.hellojni/lib/libhello-jni.so at installation Time by the package manager. *
  /static {
    system.loadlibrary ("Hello-jni");
  }


This code is very simple, the annotation is very clear, here only mention two points::

static{ 
system.loadlibrary ("Hello-jni"); 
}

Indicates that the program will load HELLO-JNI when it starts running, and the code declared by the static zone is executed before the OnCreate method. If you have multiple classes in your program, and if the Hellojni class is not the entry for your application, then Hello-jni (the complete name is libhello-jni.so) will be loaded the first time the class is used Hellojni.

Public native String Stringfromjni (); 
Public native String Unimplementedstringfromjni ();

You can see the native keyword in the declaration of both methods, which means that both methods are local methods, that is, the two methods are implemented by local code (c + +), in Java code only declarations.

Compiling the project with eclipse generates the corresponding. class file, which must be done before the next step because the. h file is required to use the corresponding. class file.

2) write the corresponding C/C + + code

At the beginning of learning, there is a problem can be confusing, the corresponding C + + code How to write, function name how to define? Here is a method, using the Javah tool to generate the corresponding. h file, and then according to this. h file to write the corresponding C + + code.

A. Generate the corresponding. h file:

Take my environment, first in the terminal to enter the directory of the HELLOJNI project just established:

braincol@ubuntu:~$ CD workspace/android/ndk/hello-jni/
LS View engineering files

braincol@ubuntu:~/workspace/android/ndk/hello-jni$ ls
Androidmanifest.xml Assets Bin Default.properties Gen Res src
You can see the files (clips) of just a few standard Android apps at the moment.

First we create a JNI folder under the Engineering directory:

braincol@ubuntu:~/workspace/android/ndk/hello-jni$ mkdir JNI
braincol@ubuntu:~/workspace/android/ndk/hello-jni$ ls
Androidmanifest.xml Assets Bin Default.properties Gen JNI Res src
The following can be generated with the corresponding. h file:

braincol@ubuntu:~/workspace/android/ndk/hello-jni$ Javah-classpath bin-d JNI com.example.hellojni.HelloJni
-classpath bin: The way to express class

-D JNI: directory that represents the generated header file

Com.example.hellojni.HelloJni is the full class name

The success of this step is based on the creation of Hellojni.class in the bin/com/example/hellojni/directory. You can now see a few more. h files under the JNI directory:

braincol@ubuntu:~/workspace/android/ndk/hello-jni$ CD jni/
braincol@ubuntu:~/workspace/android/ndk/hello-jni/jni$ ls
Com_example_hellojni_hellojni.h

Let's look at the contents of com_example_hellojni_hellojni.h:

Com_example_hellojni_hellojni.h:

/* Do isn't EDIT this file-it is machine generated/*
#include <jni.h>/
* Header for Class Com_example_hello JNI_HELLOJNI * * *
#ifndef _included_com_example_hellojni_hellojni
#define _included_com_example_hellojni_ Hellojni
#ifdef __cplusplus
extern "C" {
#endif
 * * Class:   com_example_hellojni_hellojni
 * Method:  stringfromjni
 * Signature: () ljava/lang/string;
 * *
jniexport jstring jnicall java_com_example_hellojni_hellojni_stringfromjni
 (jnienv *, jobject);
 * * Class:   com_example_hellojni_hellojni
 * method:  unimplementedstringfromjni
 * Signature: () ljava/lang/string;
* * Jniexport jstring jnicall java_com_example_hellojni_hellojni_unimplementedstringfromjni
 (JNIENV *, Jobject);
#ifdef __cplusplus
}
#endif
#endif

The Jniexport and Jnicall in the code above are JNI macros that don't need to be in the Android JNI, and of course they're not wrong to write. From the above source can see this function name that is quite long ah .... However, it is still very regular, exactly according to: Java_pacakege_class_mathod form to name.

Other words:

The Stringfromjni () method in Hello.java corresponds to the Java_com_example_hellojni_hellojni_stringfromjni () method in C + +

The Unimplementedstringfromjni () method in Hellojni.java corresponds to the

Java_com_example_hellojni_hellojni_unimplementedstringfromjni () method

Note the comments below:

Signature: () ljava/lang/string;

() ljava/lang/string () indicates that the parameter of the function is null (null here means that there are no other arguments except jnienv *, Jobject, jnienv*, Jobject is the two parameters that are required for all JNI functions, Represents the JNI environment and corresponding Java class (or object) itself, respectively, ljava/lang/string; Indicates that the return value of a function is a Java string object.

B. Preparation of the corresponding. C Document:

HELLO-JNI.C:

#include <string.h>
#include <jni.h>/
* A trivial JNI example where we use a native method
   
    * to return a new VM String. The corresponding Java source
 * file located at:
 *  apps/samples/hello-jni/project/src/com/example/ Hellojni/hellojni.java
 * *
jstring Java_com_example_hellojni_hellojni_stringfromjni (JNIEnv* env, Jobject Thiz)
{return
  (*env)->newstringutf (env, "Hello from JNI!");

   

This is just a Java_com_example_hellojni_hellojni_stringfromjni method, and Java_com_example_hellojni_hellojni_ The Unimplementedstringfromjni method was not implemented because only the Stringfromjni () method was invoked in Hellojni.java, so Unimplementedstringfromjni () It doesn't matter if the method is not implemented, but it's best to implement all the local methods defined in Java, and write an empty function ... There is better than nothing.

The Java_com_example_hellojni_hellojni_stringfromjni () function simply returns a Jstring object (corresponding to a string object in Java) with the content "Hello from JNI!". HELLO-JNI.C file has been prepared, now you can delete the com_example_hellojni_hellojni.h file, of course, it is also OK, but I still used to not need to clean up the file.

3 Compile HELLO-JNI.C build the corresponding library

A write Android.mk file

Create a new Android.mk file under the JNI directory (that is, the hello-jni.c sibling), android.mk file is the makefile file for Android, as follows:

# Copyright (C) The Android Open Source Project
#
licensed under the Apache License, Version. (the "License");
# You could not use this file, except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/license-.
#
# unless required by applicable or agreed into writing, Software
# Distributed under the License is Distri Buted on ' as is ' basis,
# without warranties OR CONDITIONS to any KIND, either express or implied.
# The License for the specific language governing permissions and # Limitations under the License
.
#
Local_path: = $ (call My-dir)
include $ (clear_vars)
local_module  : = Hello-jni
local_src_ FILES: = Hello-jni.c
include $ (build_shared_library)

This androd.mk file is very short, so let's go through the following lines:

Local_path: = $ (call My-dir)

A android.mk file must first define a good local_path variable. It is used to find source files in the development tree. In this example, the macro function ' My-dir ', provided by the compilation system, is used to return the current path (that is, the directory containing the android.mk file).

Include $ (clear_vars)

Clear_vars is provided by the compiler system, specifying that the GNU makefile clear many local_xxx variables for you (such as Local_module, Local_src_files, local_static_libraries, etc. ...) , except Local_path. This is necessary because all of the compilation control files are in the same GNU make execution environment and all variables are global.

Local_module: = Hello-jni

The compiled target object, the Local_module variable, must be defined to identify each module that you describe in the Android.mk file. The name must be unique and does not contain any spaces.

Note: The compile system automatically produces the appropriate prefix and suffix, in other words, a shared library module named ' Hello-jni ' will generate ' libhello-jni.so ' files.

Important NOTE: If you name the library ' Libhello-jni ', the compilation system will not add any Lib prefix, and will generate ' libhello-jni.so ', This is to support android.mk files from the Android platform's source code, if you really need to.

Local_src_files: = Hello-jni.c

The local_src_files variable must contain a C or C + + source code file that will be compiled into the module. Note that you don't have to list headers and include files here, because the build system will automatically find the dependent files for you, just list the source code files that are passed directly to the compiler.

Note that the default C + + source file extension is '. cpp '. It is also possible to specify a different extension, as long as you define the local_default_cpp_extension variable, and don't forget to start the little dot (i.e. '. Cxx ', not ' cxx ')

Include $ (build_shared_library)

Build_shared_library represents the compilation of the build shared library, which is compiled by the system-supplied variable, pointing to a GNU makefile script that collects since the last call ' include $ (clear_vars) ', defined in Local_ All the information in the XXX variable and decide what to compile and how to do it correctly. There are also build_static_library variables representing the generation of static libraries: lib$ (Local_module). A, build_executable represents the build executable file.

B. Generate. So shared library files

The Andro file has been written and you can now generate the corresponding. So shared library using the Ndk-build script in the Android NDK development package, as follows:

braincol@ubuntu:~/workspace/android/ndk/hello-jni/jni$ CD ...
braincol@ubuntu:~/workspace/android/ndk/hello-jni$ ls
Androidmanifest.xml Assets bin Default.properties Gen Jni Libs obj res src
braincol@ubuntu:~/workspace/android/ndk/hello-jni$ Ndk-build
Gdbserver: [arm-linux-androideabi-4.4.3] Libs/armeabi/gdbserver
Gdbsetup:libs/armeabi/gdb.setup
install:libhello-jni.so => libs/armeabi/libhello-jni.so

You can see that the Libhello-jni.so shared library has been generated correctly, let's go to the libs/armeabi/directory to see:

braincol@ubuntu:~/workspace/android/ndk/hello-jni$ CD libs/
braincol@ubuntu:~/workspace/android/ndk/hello-jni/libs$ ls
Armeabi
braincol@ubuntu:~/workspace/android/ndk/hello-jni/libs$ CD armeabi/
braincol@ubuntu:~/workspace/android/ndk/hello-jni/libs/armeabi$ ls
Gdbserver Gdb.setup libhello-jni.so

4 recompile Hellojni project in Eclipse to generate APK

Refresh the Hellojni project in Eclipse, recompile the build apk,libhello-jni.so shared library will be packaged together in the APK file. Look at the results of the operation in the simulator.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.