Android NDK Development (ii)-from Hello World

Source: Internet
Author: User

Reprint Please specify source:http://blog.csdn.net/allen315410/article/details/41805719

The previous article on the Android NDK development of some basic concepts, as well as the NDK environment to build, I believe that the friends have seen the NDK development environment should be no problem, have not set up or do not know how to build a friend please click here . So this article, as we just learned from the Java programming language, from the world-famous program "Hello world! "Start by developing our first NDK program.


NDK Directory Brief Introduction before NDK development, we have to be familiar with what is included in the NDK directory, and what is the role of these things for development? Now open the NDK's unzip directory and look at the files in the extracted directory:

1,samples directory. This directory contains some of the small examples Google has written for NDK development, including local JNI development, image processing, multiple library file development, and so on, these examples are small but all-encompassing, can understand the samples directory of small example programs, then for the NDK development, it is very good to deal with.

2,Docs directory. This directory is all about Google's documentation for developers, and it's important to guide developers on how to develop NDK in an Android environment.

3,sources directory. because Android is an open-source operating system, as part of Android's NDK, is also open source, this directory is stored in the NDK source code.

4,platforms directory. It is stored in the current NDK version of all supported Android platform version, do the NDK development of C code can also be specified by a specific version of the platform to compile, the platforms directory is a different version contains C library files and header files, There are some minor changes in different versions.

5,prebuilt directory. This is a set of tools available for developing NDK programs under Windows.

6,build directory. It contains a large number of Linux programming scripts and batch files under Windows to accomplish cross-compilation in NDK development.


Specific development 1,NDK Development steps

First, let me list the simple steps of NDK development, and then outline it, using an example of Hello world to describe the NDK development:

(1) Create an Android project

(2) Write declaration in Java code native method public native String Hellofromjni ();

(3) Create the JNI directory, write C code, the method name to correspond in C code import jni.h header file

(4) Writing android.mk files

(5) NDK compilation generates a dynamic library

(6) Java Code Load Dynamic Library. Calling native code


2,NDK Development Specific Practice

Follow the steps outlined above to establish a HelloWorld small case to step-by-step implementation of NDK development

1, create an Android project, and declare a native method in the Java code:
public class Mainactivity extends Activity {public native String javafromjni (); @Overrideprotected void OnCreate (Bundle sa Vedinstancestate) {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, write C code, the method name to correspond in C code to import jni.h header file

#include <stdio.h> #include <jni.h>jstring java_com_example_ndk_mainactivity_javafromjni (jnienv* env, Jobject obj) {return (* (*env)). Newstringutf (env, "Hello jni!");}
About this local C code how to write, still need some C language Foundation. No, we can refer to the jni.h file under the Platforms\android-19\arch-arm\usr\include directory in the NDK decompression directory, that is, the local C code needs to include the one, with Notepad open to look inside the content. Let's start with the simple format of the JNI code:

Method signature rule: 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, which can be used directly:



The following parameter list is fixed (jnienv* env, jobject obj) Form, about jnienv please define below:



Can see Ah, this jnienv originally was a masterpiece Jninativeinterface structure, this structure defines a lot of data types, then we return the type of string or method is?

  Jstring     (*newstringutf) (jnienv*, const char*);
These are the methods that I found in the jninativeinterface struct to return a string, with a parameter of jninativeinterface pointer and a string, as the above JNI code would call.

OK, so we've created the JNI local code, let's compile it and try it! Open Cygwin, switch to the project directory, execute the ndk-build command:


Take a closer look at the error log and tell us that a file called Android.mk is missing from the/jni directory, so it cannot be compiled.

3. Write the Android.mk file

How do you write this android.mk file? At this point we have to open the NDK document to see, location e:/ndk/android-ndk-r10d/docs/start_here.html, find


OK, let's start by creating a android.mk file in the JNI directory, copy and paste the above paragraph, and change the 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,NDK build the dynamic library and compile it in Cygwin:


Can see the compilation passed, the following refresh the project, you can see the project Libs directory more than a libhello.so file, this is the Android knowledge of the dynamic library.



5,java Code load Dynamic Library. Calling native code

After compiling this libhello.so file, you need to load the. So library file in Java code, the code is simple, and 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), which is the method used to load the dynamic library, where the parameter type is a string and the parameter is the name Local_module defined in the Android.mk file.


As shown in the run effect, a simple ndk developed by the Hello World is done. Friendly tip: This sample program does not support the CPU of the x86 architecture, test please open arm emulator!

Using the Javah command to help generate method signatures

The method signature rule in the known native code is this: the return value type Java_ The package name _ Class name _native method name (jnienv* env, jobject obj) , but the Java method name can be underlined in the following special cases "_ ", such as the following definition native method:

Public native String Java_from_jni ();
If we follow the above rules and apply them in C code, we define the C function as follows:

Jstring Java_com_example_ndk_mainactivity_java_from_jni (jnienv* env, Jobject obj)
The definition of the method signature is obviously inappropriate, this will cause the compilation environment is mistaken for the Mainactivity class has a Java inner class, which also contains the from inner class, from the inner class there is a method called JNI, in fact, there is no such method, so the compile time must be error. Then this example is all, in fact, according to the above method of signature rules, C language Definition native method is more troublesome, it is easy to let the hand knock error, resulting in the program can not run, in fact, we may use the JDK to provide a good javah tool to automatically generate the method signature for us, the steps are as follows:

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

Execute the "cd/d D:\workspace-mime\NDKHelloWorld\bin\classes" command into the Baunigan directory of the class bytecode file first

Then execute "Javah com.example.ndk.MainActivity"

Will get an. h file as follows:

Open this file with Notepad

/* do not EDIT This file-it are machine generated */#include <jni.h>/* Header for class com_example_ndk_mainactivity */#ifndef _in Cluded_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 we need to sign, this is the Javah tool automatically generated for us native header file, below we need to refer to this file to the project. Cut the header file directly, paste it into the project's JNI directory, then rewrite a hello.c C code, put the # include "Com_example_ndk_mainactivity.h" in the head of the code to introduce the newly generated header file, Note: In the C language, #include<xx.h> represents a header file that references the C locale (compiled), #include "Xx.h" represents the header file that references the current customization. After referencing a good header file, copy the two method signatures 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__");}
Recompile:


After recompiling, we clean the project, then refresh the project, in the Libs directory we can find the new libhello.so file we recompile, and finally implement the operation in the Java code (omitted).


ANDROID.MK Introduction

A android.mk file is used to describe your source code to the compilation system. Specifically: The file is a small part of the GNU makefile, which is parsed one or more times by the compiled system. You can define one or more modules in each android.mk file, and you can use the same source code file in several modules. The compilation system handles many detail issues for you. For example, you do not need to include your android.mk in your files and dependent files. The NDK compilation system will automatically handle these issues for you. This also means that after upgrading the NDK, you should get new Toolchain/platform support and do not need to change your android.mk file.

#交叉编译器在编译C the configuration file that the/c++ code relies on, the makefile syntax subset for Linux is        #获取当前Android. Mk path    Local_path: = $ (call My-dir)    # Initialization of variables: Local_path variables    include $ (clear_vars)    #指定编译后生成的. So file name, makefile syntax convention file name prefixed with lib and suffix.    so Local_module    : = Hello    #指定native代码文件    local_src_files: = hello.c    #指定native代码编译成动态库. So or specify to compile into a static library. A    include $ (build_shared_library)
Parameter description:

Local_module: The name of the library you want to generate, which is unique. You cannot have spaces.
After compiling, the system will automatically precede the Lib header, for example, our Hello is compiled into a libhello.so
Another feature is that if you get your name Libhello, the NDK will not add Lib to your module name before it is compiled.
But the last time you call it, you call the Hello Library.

Local_src_files: This is specifying which files you want to compile
You do not need to specify a header file to reference which dependencies, because the compiler will automatically find these dependencies automatically compiled

Include $ (build_shared_library) build_static_library
. So compiles the type of library that is generated, if it is a static library. A configuration include $ (build_static_library)

Local_cpp_extension: = cc: Specifies the extension of C + + files
Local_module: = Ndkfoo
Local_src_files: = ndkfoo.cc

Local_ldlibs + =-llog-lvmsagent-lmpnet-lmpxml-lh264android
Specifies what other libraries need to be loaded.

Another: the introduction and usage of the Android.mk file can refer to the Google NDK documentation, located in the NDK directory under the directory of the docs, programmers_guide/html/md_3__key__topics__ Building__chapter_1-section_8__android_8mk.html.



Android NDK Development (ii)-from Hello World

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.