How to compile the JNI module on the Android platform (3)

Source: Internet
Author: User

In this article, the use of ndk is mainly about the research and translation of some ndk compilation options (in fact, Google's documents have already been quite clear ). Even the test environment is slackware 12.0 + Android 1.5 R1 for Linux + JDK 1.6.0 _ 12, and ndk uses Android 1.5 ndk r1 (just decompress it directly, without installation ).

1. Start with ndk Installation
When installing ndk, you need to run one ~ A script named android-ndk-1.5_r1 under the/host-setup.sh/build/directory. After reading this script, we found that this script is mainly used to generate the out/host/config. mk file. It is mainly used to specify the judgment of the user's operating system and the supported compiler types (set CC, AR, LD and other variables in makefile)
Ndk directory introduction.

2. directory structure analysis of ndk
Go to the android-ndk-1.5_r1 directory and see the following directory structure:
Gnumakefile: a standard MAKEFILE file used to reference the build/CORE/Main. mk compilation script.
Readme. txt: the basic description is useless. All the useful documents are under the docs directory.
Apps/: stores the android project directory with the JNI interface (the project contains Java functions defined using the native keyword)
Build/: stores almost all ndk compilation scripts and necessary static link libraries.
Docs/: stores all the "official" documents of this ndk. Each document is invaluable to JNI writers.
Out/: stores some intermediate temporary files, such as. O files generated during JNI. c/. cpp file compilation.
Sources/: source code file of. c/. cpp that stores JNI files.

3. Basic usage
(1) Create an android Project
Go to the apps directory and run the following command:
Android Create project -- Target 2 -- package com. TWM -- activity ndktest -- path./ndktest/Project
Create an activity called ndktest through the command line. Note that the -- path here needs to be set. /XXXXX/project directory. This XXXXX directory is mainly used for ndk make to differentiate different projects and projects. When compiling the application. mk file, you must write application. mk to the XXXXX directory.
$ Ndk/apps/<MyApp>/application. mk

In addition, the command used to compile the JNI library is the same:
Make APP = <your app name>
The <your app name> here is actually the XXXXX directory.

(2) Add a JNI Java call interface for the project
Go to the app/ndktest/project/src/COM/TWM/ndktest directory, create a new Java file (such as ndkjni. Java), and write the code as follows:
Package com. TWM. ndktest;
Public class ndkjni {
Public native int myfunc (int A, int B );
Static {
System. loadlibrary ("ndkjni ");
}
}
Myfunc is modified using native. Therefore, this myfunc function is a function that calls JNI.

(3) Compile the application. mk file for the Java Project
This file is mainly stored in the app/ndktest directory to inform ndk of the compiling script, which JNI module is required by the current program.
It looks like this:
App_project_path: = $ (call my-DIR)/Project ---> the project directory under the current directory contains the Java interface of the JNI module.
App_modules: = ndktest ---> the name of the current module is ndktest.

(4) understand the Java program package Layers
Take the current project as an example. The package com. TWM. ndktest in the code above defines the class named ndkjni. Therefore, according to the package hierarchy, you can define the function according to the function naming rules of the JNI file:
Jniexport jint jnicall java_com_twm_ndktest_ndkjni_myfunc (jnienv * ENV, jobject thiz, jint A, jint B );
Of course, defining the JNI function manually based on the package hierarchy is still very painful. You can use the javah tool:
Mkdir-P apps/ndktest/project/JNI
CD apps/ndktest/project/JNI
Javah-classpath "../bin/classes" com. TWM. ndktest. ndkjni
Then a file named com_twm_ndktest_ndkjni.h is automatically generated. The content in the file is basically the same as that generated manually:
/* Do not edit this file-it is machine generated */
# Include <JNI. h>
/* Header for class com_twm_ndktest_ndkjni */

# Ifndef _ included_com_twm_ndktest_ndkjni
# DEFINE _ included_com_twm_ndktest_ndkjni
# Ifdef _ cplusplus
Extern "C "{
# Endif
/*
* Class: com_twm_ndktest_ndkjni
* Method: myfunc
* Signature: (ii) I
*/
Jniexport jint jnicall java_com_twm_ndktest_ndkjni_myfunc
(Jnienv *, jobject, jint, jint );

# Ifdef _ cplusplus
}
# Endif
# Endif
Now, with the definition of this function, you can prepare to write JNI.

(5) enter the source directory
Create the directory ndktest and place two files in it. One is named like A. C, and the other is a compilation script file called Android. mk.
The content is as follows:
Local_path: = $ (call my-DIR)

Include $ (clear_vars)

Local_module: = ndktest ---> The Name Of The JNI module is specified here. The generated so library should be called libndktest. So. The name must be the same as app_modules in the application. mk file.
Local_src_files: = A. C

Include $ (build_shared_library) ---> This tells the library generated by the compilation script to be a shared library (ndk can generate dynamic and static libraries ).

The content written in A. C is as follows:
Jniexport jint jnicall
Java_com_twm_ndktest_ndkjni_myfunc (jnienv * ENV, jobject thiz, jint A, jint B)
{
Return A + B;
}

(6) start compiling the JNI Module
First enter the android-ndk-1.5_r1 directory, and then run the following command:
Make APP = ndktest [Press enter]
At this time, we will see that it starts to compile and has established the libs/armeabi/directory under the apps/ndktest/projects/directory, and copied the generated libndktest. So to this directory.
Someone may ask why its compilation parameters are missing. How can I debug them ?! In fact, it is very simple, just add a compilation parameter.
Make APP = ndktest v = 1 [Press enter]

You will see the following output (I changed the. C mentioned above to ndktest. c In the test program, so the content is slightly different ):
Wayne @ WAYNE :~ /Android-ndk-1.5_r1 $ make APP = ndktest v = 1
Android ndk: Building for application 'ndktest'
Compile thumb: ndktest <= sources/ndktest. c
Build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/ARM-Eabi-gcc-ibuild/platforms/Android-1.5/arch-arm/usr/include-March = armv5te-mtune = XScale- msoft-float-FPIC-mthumb-interwork-ffunction-sections-funwind-tables-fstack-protector-fno-short-enums-d1_arm_arch_5 _-d1_arm_arch_5t _-functions __- d__arm_arch_5te _-isources/ndktest-dandroid-O2-dndebug-g-C-MMD-MP-MF out/apps/ndktest/Android-1.5-arm/objs/ndktest. o. d. TMP sources/ndktest. c-o out/apps/ndktest/Android-1.5-arm/objs/ndktest. O
Build/CORE/mkdeps. sh out/apps/ndktest/Android-1.5-arm/objs/ndktest. O out/apps/ndktest/Android-1.5-arm/objs/ndktest. o. d. TMP out/apps/ndktest/Android-1.5-arm/objs/ndktest. o. d
Sharedlibrary: libndktest. So
Build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/ARM-Eabi-gcc-nostdlib-wl,-soname, libndktest. so-wl,-shared,-bsymbolic out/apps/ndktest/Android-1.5-arm/objs/ndktest. o-wl, -- whole-archive-wl, -- no-whole-archive build/platforms/Android-1.5/arch-arm/usr/lib/libc. so build/platforms/Android-1.5/arch-arm/usr/lib/libstdc ++. so build/platforms/Android-1.5/arch-arm/usr/lib/libm. so-wl, -- no-undefined-wl, -rpath-link = build/platforms/Android-1.5/arch-arm/usr/lib/home/Wayne/android-ndk-1.5_r1/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin /.. /lib/GCC/ARM-Eabi/4.2.1/interwork/libgcc. a-O out/apps/ndktest/Android-1.5-arm/libndktest. so
Install: libndktest. So => apps/ndktest/project/libs/armeabi
Mkdir-P apps/ndktest/project/libs/armeabi
Install-P out/apps/ndktest/Android-1.5-arm/libndktest. So apps/ndktest/project/libs/armeabi/libndktest. So
Build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/ARM-Eabi-strip -- strip-Debug apps/ndktest/project/libs/armeabi/libndktest. So

(7) start compiling Android local Java program
Go to the apps/ndktest/project directory and run ant debug to generate the APK package of the debugging version. Note that the generated libndktest. So package is automatically included in the APK package. This can be verified by unzipping the APK file.

This is the entire process of compiling the JNI program by Android-ndk. It is indeed much simpler than the method described in the previous article. Here is a summary:
(A) Create a Java project with the native keyword declaration in the apps directory. (Note: The Directory needs to be added to the application. mk file)
(B) Create a real JNI Module Directory in the sources directory, which must contain a file called Android. mk.
(C) The application. mk in apps and Android. mk in the sources directory must "echo each other" in the module name ".
(D) The compile method is to enter the android-ndk-1.5_r1 directory and run make APP = <your app name> V = 1 to generate the JNI library, make APP = <your app name> clean can also be cleared.

I hope this article will be helpful to anyone who is devoted to Android development and transplantation.

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.