Android NDK Development (II) -- from Hello World, androidndk

Source: Internet
Author: User

Android NDK Development (II) -- from Hello World, androidndk

Reprinted please indicate the source:Http://blog.csdn.net/allen315410/article/details/41805719

The previous article describes some basic concepts of Android NDK development and the establishment of the NDK environment. I believe that the establishment of the NDK development environment is no problem, if you have not set up or do not know how to set up a project, pleaseClick here. So this article, like learning the Java programming language, uses the World-renowned program "Hello World !" Start, develop our first NDK program.


A Brief Introduction to the NDK directory before developing NDK, we must be familiar with what is contained in the NDK directory, and what is the role of these things for development? Now open the decompressed directory of NDK and check the files in the decompressed directory:

1,Samples Directory.This directory contains some small examples written by Google for NDK development, including local JNI development, image processing, and development of multiple library files. These examples are small but comprehensive, if you can understand the small example programs under the samples directory, it will be a good deal for NDK development.

2,Docs directory.This directory stores all the documents provided by Google to developers, which is very important for developers to develop NDK In the Android environment.

3,Sources directory.Because Android is an open-source operating system, NDK, which is a part of Android, is also open-source. This directory stores the NDK source code.

4,The platforms directory.It stores the versions of all android platforms supported by the current ndk version. The C code for NDK development can also be specified to be compiled under a specific version platform, the platforms directory stores the library files and header files of C in different versions. Different versions have slight changes.

5,Prebuilt directory.This is a set of tools provided for developing ndk programs in Windows.

6,Build directory.It stores a large number of Linux programming scripts and Windows batch files to complete cross-compilation in ndk development.


Development steps 1: NDK

First, I will first list the simple steps of NDK development, and then use this outline to describe NDK development with a Hello World instance:

(1) Create an android Project

(2) write the Declaration native METHOD public native String helloFromJNI () in JAVA code ();

(3) create the jni directory and write the c code. The method name should correspond to the jni. h header file imported in the c code.

(4) Compile the Android. mk File

(5) dynamic library generated by Ndk Compilation

(6) Java code load dynamic library. Call native code


2. NDK development practices

The following describes how to build a HelloWorld case to implement NDK development step by step.

1. Create an Android project and declare an native method in the Java code:
public class MainActivity extends Activity {public native String javaFromJNI();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, javaFromJNI(),Toast.LENGTH_SHORT).show();}});}}
2. Create the jni directory and write the c code. The method name should correspond to the jni. h header file imported in the c code.

#include<stdio.h>#include<jni.h>jstring Java_com_example_ndk_MainActivity_javaFromJNI(JNIEnv* env, jobject obj) {return (*(*env)).NewStringUTF(env, "hello jni!");}
Some basic C language is required for writing the local C code. You can refer to the jni in the platforms \ android-19 \ arch-arm \ usr \ include directory under the ndk decompression directory. h file, which must be included in the local C code. Open it in notepad and check the content. Let's take a look at the simple format of the JNI code:

Method signature rules:Return Value Type: Java _ package name_class name_native method name (JNIEnv * env, jobject obj)
The return value type is the pre-defined custom C type in the JNI header file. You can use it directly:



The following parameter list is fixed (JNIEnv * env, jobject obj). For details about JNIEnv, see the following definition:



As you can see, this JNIEnv is originally a structure named JNINativeInterface. This struct defines many data types. Which of the following is the type or method of the returned string?

  jstring     (*NewStringUTF)(JNIEnv*, const char*);
The above is the method for returning the string I found in the JNINativeInterface struct. The parameter is the JNINativeInterface pointer and a string, which can be called as used in the preceding JNI code.

Okay. Now we have created the JNI local code. Let's compile it and try it! Open cygwin, switch to the project directory, and run the ndk-build command:


Take a closer look at the error log and tell us that a file named Android. mk is missing in the/jni Directory, which causes compilation failure.

3. Compile the Android. mk File

How to write this Android. mk file? At this time we have to open the NDK document to see the location E:/NDK/android-ndk-r10d/docs/Start_Here.html, find


Well, we will first create an Android. mk file under the jni directory, copy and paste the above section, and change LOCAL_MODULE and LOCAL_SRC_FILES to our own name:

    LOCAL_PATH := $(call my-dir)    include $(CLEAR_VARS)    LOCAL_MODULE    := Hello    LOCAL_SRC_FILES := Hello.c    include $(BUILD_SHARED_LIBRARY)
4. Compile ndk to generate a dynamic library and compile it in cygwin:


We can see that the compilation is successful. Refresh the project below, and we can see that there is an additional libHello. so file under the libs directory of the project. This is the dynamic library recognized by Android.



5. Java code load dynamic library. Call native code

After compiling the libHello. so file, you need to load the. so library file in the Java code. The code is very simple. Then Toast to see the effect:

public class MainActivity extends Activity {static {System.loadLibrary("Hello");}public native String javaFromJNI();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, javaFromJNI(),Toast.LENGTH_SHORT).show();}});}}
System. loadLibrary (String file name) is used to load the dynamic library. The parameter type is String, and the parameter is the name defined by LOCAL_MODULE In the Android. mk file.


The running effect is shown. Here, a simple ndk developed Hello World is complete.Tip: This example does not support cpu Of The x86 architecture. Enable the arm Simulator for testing!

Use the javah command to generate a method Signature

The method signature rules in native code are known as follows: Return Value Type: Java _ package name_classname_native method name (JNIEnv * env, jobject obj, java method names can contain underscores (_). For example, the native method is defined as follows:

public native String java_From_JNI();
Assume that, according to the above rules, the C function is defined in the C code:

jstring Java_com_example_ndk_MainActivity_java_From_JNI(JNIEnv* env, jobject obj)
The method signature defined in this way is obviously inappropriate. This will cause the compilation environment to mistakenly assume that there is a java internal class under the MainActivity class, which also contains the From internal class, there is a jni method in the From internal class. In fact, this method is not used, so an error is certainly returned during compilation. This example is just an example. In fact, according to the above method signature rules, defining the native method in the C language is troublesome, and it is easy for people to make mistakes, resulting in program running failure, in fact, we can use the javah tool provided by JDK to automatically generate method signatures for us. The steps are as follows:

1. In windows Command mode, switch to the directory where the class bytecode file under the project package is located. The path in this example is D: \ workspace-mime \ NDKHelloWorld \ bin \ classes.

Run the "cd/d D: \ workspace-mime \ NDKHelloWorld \ bin \ classes" command to enter the package name root directory of the class bytecode file.

Then run "javah com. example. ndk. MainActivity"

You will get a. h file as shown in the following figure:

Open this file in Notepad

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_ndk_MainActivity */#ifndef _Included_com_example_ndk_MainActivity#define _Included_com_example_ndk_MainActivity#ifdef __cplusplusextern "C" {#endif/* * Class:     com_example_ndk_MainActivity * Method:    javaFromJNI * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_ndk_MainActivity_javaFromJNI  (JNIEnv *, jobject);/* * Class:     com_example_ndk_MainActivity * Method:    java_From_JNI * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_ndk_MainActivity_java_1From_1JNI  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
The above is the method signature we need. This is the native header file automatically generated by the javah tool. Next we need to reference this header file to the project. Cut the header file, paste it to the jni directory of the project, and then rewrite a Hello. c code, put # include "com_example_ndk_MainActivity.h" in the Code header to introduce the header file just generated. Note: # include <xx in C. h> indicates referencing the header file that comes with the C language environment (Compilation), # include "xx. h "indicates referencing the current custom header file. After the header file is referenced, copy the signature of the two methods in the header file to implement the logic:

#include<stdio.h>#include<jni.h>#include"com_example_ndk_MainActivity.h"JNIEXPORT jstring JNICALL Java_com_example_ndk_MainActivity_javaFromJNI(JNIEnv* env, jobject obj) {return (*env)->NewStringUTF(env, "hello jni!");}/* * Class:     com_example_ndk_MainActivity * Method:    java_From_JNI * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_ndk_MainActivity_java_1From_1JNI(JNIEnv* env, jobject obj) {return (*env)->NewStringUTF(env, "hello_jni__");}
Re-compile:


After re-compilation, we clean the project and refresh the project. In the libs directory, we can find the new libHello. so file, and finally implement the operation (Omitted) in the Java code ).


About Android. mk

An Android. mk file is used to describe your source code to the compilation system. Specifically, this file is a small part of GNU Makefile and will be parsed once or multiple times by the compilation system. You can define one or more modules in each Android. mk file. You can also use the same source code file in several modules. The compilation system handles many details for you. For example, you do not need to list header files and dependent files in your Android. mk file. The NDK compilation system automatically handles these problems for you. This also means that after you upgrade the NDK, you should get the new toolchain/platform support and do not need to change your Android. mk file.

# The Cross-compiler compiles the configuration file on which C/C ++ Code depends, and the syntax subset of makefile in linux # obtain the current Android. mk path LOCAL_PATH: = $ (call my-dir) # initialization feature of the variable: The variable include $ (CLEAR_VARS) of LOCAL_PATH will not be reinitialized # specify the generated after compilation. so file name. The makefile syntax stipulates that the file name should be prefixed with lib and suffix. so LOCAL_MODULE: = Hello # specify the native code file LOCAL_SRC_FILES: = Hello. c # compile native code into a dynamic library. so can be compiled into a static library. a include $ (BUILD_SHARED_LIBRARY)
Parameter introduction:

LOCAL_MODULE: the name of the library you want to generate. This name is unique and cannot contain spaces.
After compilation, the system automatically adds the lib header to the front. For example, our Hello is compiled into libHello. so.
Another feature is that if you name it libHello, after compiling, ndk won't add lib to your module name.
However, when you finally call the Hello library

LOCAL_SRC_FILES: Specifies the files to be compiled.
You do not need to specify the header file and reference which dependencies, because the compiler will automatically find these dependencies for automatic compilation.

Include $ (BUILD_SHARED_LIBRARY) BUILD_STATIC_LIBRARY
The type of the library generated after. so compilation. If it is a static library, configure include $ (BUILD_STATIC_LIBRARY)

LOCAL_CPP_EXTENSION: = cc: Specifies the extension of the c ++ file.
LOCAL_MODULE: = ndkfoo
LOCAL_SRC_FILES: = ndkfoo. cc

LOCAL_LDLIBS + =-llog-lvmsagent-lmpnet-lmpxml-lhsf-android
Specify the database to be loaded.

Another: about Android. mk file introduction and usage can refer to the document provided by Google NDK, location is ndk extract directory under the docs directory, Programmers_Guide/html/md_3__key__topics__building__chapter_1-section_8__android_8mk.html.



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.