Android Development notes-ndk programming example

Source: Internet
Author: User

On Android, most applications are developed based on Java. To use C or C ++ programs or libraries, you need to use ndk. Ndk is short for Native Development Kit. It is a tool set that integrates the cross-compiling environment of Android and provides a set of convenient makefiles to help developers quickly develop C or C ++ dynamic libraries, and automatically package the so and Java programs into APK to run on Android.

 

Well, let's talk less about it. We will explain the application of ndk with a simple example.

1. Build a Development Environment

Although this step has no technical knowledge, it is helpful for beginners to have a good entry guide.

1.1 Android SDK Construction

First, the android SDK must be installed to develop the android program. Of course, the Java environment is also essential. Install JDK and eclipse first. You can select a new version because the new Android SDK does not support the old version.

1.1.1 JDK can use V5 or V6 version, http://java.sun.com/javase/downloads/index.jsp

1.1.2 eclipse can use version 3.4 or 3.5, http://www.eclipse.org/downloads/. Of course, if you need other Java development environment, you can not use eclipse, but this will not use ADT (Android development tools) plug-in. It is recommended that you use eclipse for development. After all, it is more authoritative and convenient.

1.1.3 install SDK

Android SDK for http://androidappdocs.appspot.com/sdk/tools-notes.html

1.1.4 install ADT for ipvs. In eclipse, fill in the Update site https://dl-ssl.google.com/Android/eclipse/, and then select install ADT.

1.1.5 next, We will select the Android platform and components. In the window system, run the SDK setup.exe; in the Linux system, run the android program under the tools directory, you can select the required Android platform and components.

After completing the above work, you can develop Android applications. You can use eclipse to create an android Project, which is a simple hello Android project, and then run it in the simulator. For detailed operations, see the instructions on the android development website.

1.2 Android ndk Construction

We have set up the SDK environment above and can develop Java applications. To develop C Programs, you must build an ndk environment.

Ndk provides the following content:

Libc (C library) headers

Libm (Math Library) headers

JNI interface Headers

BZ (zlib compression) headers

Blog (Android logging) Header

A minimal set of headers for C ++ support

1.2.1 install ndk

Download the ndk installation package, http://Androidappdocs.appspot.com/sdk/ndk/index.html, download and unzip to use.

1.2.2 if it is in the Linux development environment, you can use it. In the Windows environment, cygwin must be installed. Cygwin: http://www.cygwin.com/

In this way, the ndk environment has been set up. Next we will conduct practical exercises.

 

2. ndk Development Instance

To use ndk, you must first understand the concept of JNI. What is JNI?

2.1 hello-JNI

This is an example program that comes with ndk. The installation instructions on the official website should be step-by-step and there should be no problem. I will not elaborate on it here.

2.2 my God I did it

The first step in learning is imitation. Follow the hello-JNI example above to create your own ndk program. In this process, the relevant content and concepts are analyzed and described.

 

First, create your own ndk project. We create our own project myjni under the ndk sample directory, and then under this file clip, we create two directories: JNI and SRC. JNI is used to store our c files, SRC is the Java interface file of the C library called. Create a directory, and then create the file JNI/myjni. C. The file is simple, that is, output a string with the following content:

# Include <string. h>
# Include <stdio. h>
# Include <JNI. h>
# Include <Android/log. h>
# Define log_tag "myjni"
# Define Logi (...) _ android_log_print (android_log_debug, log_tag, _ va_args __)
Static char s_string [] = "My God, I did it! ";
Jstring
Java_com_jpf_myjni_myjni_stringfromjni (jnienv * ENV,
Jobject thiz)
{
Logi ("myjni is called! ");
Return (* env)-> newstringutf (ENV, s_string );
}

The only difference between this program and hello-JNI is that the header file <Android/log. h> is referenced. In this header file, the function _ android_log_print () is declared. Logs can be output based on different log levels to facilitate code debugging. In ndk, printf () cannot be output, so we need to use the log library to output the content in our C code library through the Java console. Call function _ android_log_print () to view the related output information in eclipse.

Note:

In the c file, the function name is defined as follows: java_com_jpf_myjni_myjni_stringfromjni. What do you do? This is the JNI standard and the definition must follow the following format:

Java _ packagename _ classname _ methodname,

Example: Java _ com_jpf_myjni _ myjni _ stringfromjni

Create the JNI/Android. mk file. This file is the makefile of our local C code. The file content is as follows:

Local_path: = $ (call my-DIR)

 

Include $ (clear_vars)

 

Local_module: = myjni

Local_src_files: = myjni. c

 

Local_ldlibs + =-llog

 

Include $ (build_shared_library)

Describes the makefile statements.

Local_path: = $ (call my-DIR) is used to specify the compiling path. Call the macro my-Dir to obtain the current working path.

Include $ (clear_vars) clear_vars is provided by the compilation system to specify a gnu makefile file and add this sentence. The main purpose is to clear all local_xxx., such as local_module and local_ldlibs. Add this sentence at the beginning of each new module.

Local_module: = myjni defines the module name. The library to be compiled will be named like this. If the dynamic library is compiled, the Library name is libmyjni. so. note that if you define the module as libmyjni, the system will not add the Lib prefix when generating a dynamic library. The generated dynamic library name is libmyjni. so.

Local_ldlibs + =-llog specifies the library to be connected separately. We use the log library in the code, so this sentence is added here.

The include $ (build_shared_library) statement indicates that the library to be produced will be a shared library and a dynamic link library. To produce a static database, you can write: include $ (build_static_library ).

 

After writing the C and makefile files, can I compile them? Let's give it a try. In cygwin, go to the project directory and run ndk-build. The following result is displayed:

Admin @ lenovo-0e47e162/Android/android-ndk-r4/samples/myndk

 

$ Ndk-build

Android ndk: cocould not find application's manifest from current directory.

Android ndk: please ensure that you are inside the project's directory!

/Android/android-ndk-r4/build/CORE/build-local.mk: 74: *** Android ndk: aborting

. Stop.

The manifest file is missing. The old version of ndk has an app in the project, which contains the application file and application. mk. In the current version, we do not need to write application. mk by ourselves, but we still need project-related configuration information. So how to do it? Do I need to manually write the manifest file? No. You only need to create a project in eclipse. These configuration files are automatically generated.

As mentioned above, it is used to place java files under the SRC clip of the project. Open eclipse and create an android project. The project name is myjni. Select the path of the ndk. Note that the project name and package name must be consistent with the c file above.

(Java _ com_jpf_myjni _ myjni _ stringfromjni)

After the project is created, edit the src/COM/jpf/myjni. Java file with the following content:

Package com. jpf. myjni;

 

Import Android. App. activity;

Import Android. widget. textview;

Import Android. OS. Bundle;

 

Public class myjni extends activity {

/** Called when the activity is first created .*/

@ Override

Public void oncreate (bundle savedinstancestate ){

Super. oncreate (savedinstancestate );

Textview TV = new textview (this );

TV. settext (stringfromjni ());

System. Out. println ("Here we go ...");

Setcontentview (TV );

System. Out. println ("done! ");

}

 

Public native string stringfromjni ();

Static {

System. loadlibrary ("myjni ");

}

}

Notes:

Public native string stringfromjni (); this statement contains the native keyword, indicating that the method is a local method.

System. loadlibrary ("myjni"); this statement is used to load our c dynamic library. The specific implementation of the method stated above is in the library we load.

 

Build the project, compile it again, and run ndk-build in cygwin. The result is OK.

Admin @ lenovo-0e47e162/Android/android-ndk-r4/samples/myndk

$ Ndk-build

Compile thumb: myjni <=/Android/android-ndk-r4/samples/myndk/JNI/myjni. c

Sharedlibrary: libmyjni. So

Install: libmyjni. So =>/Android/android-ndk-r4/samples/myndk/libs/armea

Bi

We can see that the required shared library has been generated and installed. Then you can generate an APK.

Build the project in cygwin. After compilation, we will see our APK package under the bin directory of the project.

Okay. Let's try to see if it works normally. In eclipse, select Android Application as the execution method and click Run. The following console output is displayed:

 

[2010-07-07 14:26:18-myjni] ------------------------------

[14:26:18-myjni] Android launch!

[14:26:18-myjni] ADB is running normally.

[14:26:18-myjni] Ming com. jpf. myjni. myjni activity launch

 

[14:26:18-myjni] Automatic Target mode: using existing emulator 'emulator-5554 'running compatible avd' android21'

[14:26:18-myjni] Warning: application does not specify an API level requirement!

[14:26:18-myjni] device API version is 7 (Android 2.1-update1)

[5554 14:26:18-myjni] uploading myjni.apk onto device 'emulator-100'

[14:26:18-myjni] installing myjni.apk...

[14:26:24-myjni] success!

[14:26:25-myjni] Starting activity com. jpf. myjni. myjni on Device

[14:26:29-myjni] activitymanager: Starting: intent {act = android. intent. action. main cat = [android. intent. category. launcher] CMP = com. jpf. myjni /. myjni}

The above warning is the version number of the API that we have not specified. As shown below, this warning will not be available.

 

For the execution result:

Here is the output of logcat:

We can see our output myjni: myjni is called!

 

2.3 study hard

With the above foundation, we can use ndk for project development.

We often encounter this problem: Porting some existing mature C libraries to the Android platform. Through the above introduction, we know that we need to use JNI to wrap the existing C library, and then provide Java interfaces for the upper layer to call.

 

The first problem is the compilation and testing of the C library. In fact, Android uses the Linux kernel at the underlying layer. Therefore, like other Linux program development, cross compilation cannot be performed. However, we need to pay attention to some special features of Android. The following is a simple example of how to use ndk to test a C application terminal.

First, create the study-hadr/study-hard.c file, the program is very simple, is the hello World C program.

# Include <string. h>

# Include <stdio. h>

 

Static char s_string [] = "study hard! ";

 

Int main ()

{

Printf ("% s/n", s_string );

Return 0;

}

Although the program is simple, the compilation of this program is not simple.

In Linux, you only need to execute:

The GCC-o study-hard study-hard.c can generate the application study-hard.

It's not that simple in Android. In the Windows environment development environment, the cross tool chain used, directory is/android-ndk-r4/build/prebuilt/Windows/arm-eabi-4.4.0. In the bin path of this directory, you will see many arm-Eabi prefix tools, which are the compilation tools used by Android. So where are the C library and C header files? For Android, different platforms have different libraries and header files, which need to be selected by ourselves. For example, if we want to use platform5

The path of the C header file is:

/Android-ndk-r4/build/platforms/Android-5/arch-arm/usr/include

The C library path is:

/Android-ndk-r4/build/platforms/Android-5/arch-arm/usr/lib

Well, we know the C compilation tool chain, and the C library path and the C header file path. We should be able to compile it. Write a simple makefile and try it. The result is incorrect. Crt0.o not found.

 

This error is terrible. It indicates that crt0.o cannot be found during the link. Add the following sentence to makefile:

Ldflags + =-nostdlib

-Nostdlib indicates that the system standard Startup File and standard library file are not connected. Only the specified file is passed to the connector.

 

At this time, the compilation result is:

 
The error indicates that puts cannot be found during the link. This function is in the C library. Let's add the following statement and try again:

Ldflags + =-lC

 

Modify the link option, add the link to the DL library, and try again:

Ldflags + =-LC-LDL

 

The executable file is generated this time, but there is still warning. In the generated executable file, the entry _ start is not found. This problem is also strange. We can view the generated executable file:

Readelf-a study-hard

The generated executable file is found to have no entry function. Why?

 

In Linux, use the-V option to track the GCC compilation process of the hello World Program. You will find that in the Link process, except hello. o, crt1.o and crtn are also linked. O and other files, which constitute the processing parts of the ELF File, such as program entry and program exit, during the process of generating executable programs.

View the specified C Library:

 

You will find that there are three. O files with CRT headers in the C library. Modify the makefile to link the crtbegin and crtend files:

Extra_objs: = $ (path_prefix)/lib/crtbegin_dynamic.o $ (path_prefix)/lib/crtend_android.o

... ...

$ (CC) $ (cflags)-o $ (target) $ (objs) $ (extra_objs) $ (ldflags)

The result is as follows: the compilation is successful.

Let's put the compiled program on Android and run it to see the effect.

The display program is not found. What's going on? Continue to study androidndk documents. We also need to modify the makefile:

Ldfalgs + =-bdynamic-wl,-dynamic-linker,/system/bin/linker

Specifies the link to the dynamic library. The dynamic connector is/system/bin/linker.

After compilation, run again and finally see "study hard! "

 

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.