标签:android style blog http color io os ar 使用
Android NDK 开发跟其它开发一样,首先需要配置好开发环境,本文以 Ubuntu系统为例介绍如何进行 Android NDK 开发环境的配置。
什么是 Android NDK 呢? NDK(Native Development Kit) 是一个允许开发者用一些本地语言(C/C++)编写 Android App 的部分功能的工具集。对于一些特定的 App,NDK 非常有利于我们直接使用现成的用 C/C++ 编写的代码库(但对于大多数 App 来说,NDK 是没有必要的)。使用 NDK 进行 C/C++ Android 开发的基本结构和流程如下图(来自shihongzhi博客 ):
NDK 开发过程中涉及到将 C/C++ 程序编译为动态库(.so文件),由于Ubuntu系统中已经安装有 C/C++ 的编译工具 gcc/g++,以及 make 工具,所以在此不作介绍。另外还需要安装 JDK,并配置 Java 的环境变量,这个不是本文重点,在此也不作介绍了。
下面重点讲讲 Android 相关 SDK 的安装和配置,主要涉及到 Android SDK,ADT,NDK等。要进行 Android 开发,首先需要安装 Android SDK,要在 Eclipse 中进行开发的话,还需在 Eclipse 中安装 ADT(Android Develop Tools),在 Android 官网上提供了 SDK 和 包含 ADT 的 Eclipse 的集成开发包,可以一起下载:adt-bundle-linux-x86-20140321.zip。另外,还需要安装 NDK,下载地址:android-ndk-r9d-linux-x86.tar.bz2。下载完这两个压缩包后解压并移动到 /usr/local 目录下:
(1)先下载安装NDK。
下载地址:http://developer.android.com/sdk/ndk/index.html
下载后解压缩就可以用了。
(2)打开Eclipse,新建一个Android工程(这里为AntiVirus),在工程目录AntiVirus下新建jni文件夹,该文件夹就用来保存NDK需要编译的文件代码等。
(3)新建并配置一个Builder:
(a)Project->Properties->Builders->New,新建一个Builder。
(b)在弹出的【Choose configuration type】对话框,选择【Program】,点击【OK】:
(c)在弹出的【Edit Configuration】对话框中,配置选项卡【Main】。
在“Name“中输入新builders的名称(这里为Ndk_Builder)。
在“Location”中输入nkd-build(windows为nkd-build.cmd)的路径。
(我的是/usr/local/android-ndk-r10/ndk-build,根据各自的ndk路径设置,也可以点击“Browser File System…”来选取这个路径)。
在“Working Diretcoty”中输入${workspace_loc:/AntiVirus}(也可以点击“Browse Workspace”来选取AntiVirus目录)。
(d)【Edit Configuration】对话框中,配置选项卡【Refresh】。
勾选“Refresh resources upon completion”,
勾选“The entire workspace”,
勾选“Recuresively include sub-folders”。
(e)【Edit Configuration】对话框中,配置选项卡【Build options】。
勾选“After a “Clean””,
勾选“During manual builds”,
勾选“During auto builds”,
勾选“Specify working set of relevant resources”。
点击“Specify Resources…”
勾选AntiVirus工程的“jni“目录,点击”finish“。
点击“OK“,完成配置。
OK,到这里Eclipse就能够自动调用NDK编译jni目录下的C/C++代码了。
(4)在TestNdk工程中新建一个TestJni.java类(为了调用C/C++代码),其内容如下:
1 package com.wat.antivirus; 2 3 public class TestJni { 4 static { 5 System.loadLibrary("HelloJni"); // 加载 jni 动态库 6 } 7 8 public native String helloSay(); // 返回字符串 9 public native int helloAdd(int a,int b); // 两个整数相加 10 public native int helloSub(int a,int b); // 两个整数相减 11 public native int helloMul(int a,int b); // 两个整数相乘 12 public native int helloDiv(int a,int b); // 两个整数相除 13 }
(5)在 Eclipse 中 build 一下生成对应 .class 文件,然后使用 javah 工具根据该 class 文件自动生成 jni API 的头文件。在 AntiVirus工程根目录下执行如下命令:
javah -classpath ./bin/classes -d jni com.wat.antivirus.TestJni
其中 -classpath ./bin/classes
表示类的路径,-d jni
表示生成的头文件存放的目录, com.wat.antivirus.TestJni
则是完整类名。执行命令后,在 ~/workspace/AntiVirus/jni
目录下生成了C++头文件 com_wat_antivirus_TestJni.h
,文件内容如下:
1 /* DO NOT EDIT THIS FILE - it is machine generated */ 2 #include <jni.h> 3 /* Header for class com_wat_antivirus_TestJni */ 4 5 #ifndef _Included_com_wat_antivirus_TestJni 6 #define _Included_com_wat_antivirus_TestJni 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 /* 11 * Class: com_wat_antivirus_TestJni 12 * Method: helloSay 13 * Signature: ()Ljava/lang/String; 14 */ 15 JNIEXPORT jstring JNICALL Java_com_wat_antivirus_TestJni_helloSay 16 (JNIEnv *, jobject); 17 18 /* 19 * Class: com_wat_antivirus_TestJni 20 * Method: helloAdd 21 * Signature: (II)I 22 */ 23 JNIEXPORT jint JNICALL Java_com_wat_antivirus_TestJni_helloAdd 24 (JNIEnv *, jobject, jint, jint); 25 26 /* 27 * Class: com_wat_antivirus_TestJni 28 * Method: helloSub 29 * Signature: (II)I 30 */ 31 JNIEXPORT jint JNICALL Java_com_wat_antivirus_TestJni_helloSub 32 (JNIEnv *, jobject, jint, jint); 33 34 /* 35 * Class: com_wat_antivirus_TestJni 36 * Method: helloMul 37 * Signature: (II)I 38 */ 39 JNIEXPORT jint JNICALL Java_com_wat_antivirus_TestJni_helloMul 40 (JNIEnv *, jobject, jint, jint); 41 42 /* 43 * Class: com_wat_antivirus_TestJni 44 * Method: helloDiv 45 * Signature: (II)I 46 */ 47 JNIEXPORT jint JNICALL Java_com_wat_antivirus_TestJni_helloDiv 48 (JNIEnv *, jobject, jint, jint); 49 50 #ifdef __cplusplus 51 } 52 #endif 53 #endif
(6)在jni目录下新建一个Android.mk文件,其内容如下(详细的语法以后再另外解释):
1 LOCAL_PATH := $(call my-dir) 2 3 include $(CLEAR_VARS) 4 5 LOCAL_MODULE := HelloJni 6 7 LOCAL_SRC_FILES := HelloJni.c 8 9 include $(BUILD_SHARED_LIBRARY)
(7)将com_wat_antivirus_TestJni.h
拷贝到AntiVirus工程的jni目录下, 然后新建一个HelloJni.c文件完成头文件中函数的实现,其内容如下:
1 #include <string.h> 2 #include <jni.h> 3 4 jstring 5 Java_com_wat_antivirus_TestJni_helloSay( JNIEnv* env, 6 jobject thiz ) 7 { 8 #if defined(__arm__) 9 #if defined(__ARM_ARCH_7A__) 10 #if defined(__ARM_NEON__) 11 #if defined(__ARM_PCS_VFP) 12 #define ABI "armeabi-v7a/NEON (hard-float)" 13 #else 14 #define ABI "armeabi-v7a/NEON" 15 #endif 16 #else 17 #if defined(__ARM_PCS_VFP) 18 #define ABI "armeabi-v7a (hard-float)" 19 #else 20 #define ABI "armeabi-v7a" 21 #endif 22 #endif 23 #else 24 #define ABI "armeabi" 25 #endif 26 #elif defined(__i386__) 27 #define ABI "x86" 28 #elif defined(__x86_64__) 29 #define ABI "x86_64" 30 #elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ 31 #define ABI "mips64" 32 #elif defined(__mips__) 33 #define ABI "mips" 34 #elif defined(__aarch64__) 35 #define ABI "arm64-v8a" 36 #else 37 #define ABI "unknown" 38 #endif 39 40 return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI "."); 41 }
编辑com_ndk_test_JniClient.c并保存后,可以看到TestNkd工程下的obj/local/armeabi目录下将自动生成libTestNdk.so库。
(8)在AntiVirus.java中完成对TestJni.java中函数的调用:
1 package com.wat.antivirus; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.TextView; 8 9 10 public class MainActivity extends Activity { 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 17 Button btn = (Button)findViewById(R.id.btn_cal); 18 btn.setOnClickListener(new Button.OnClickListener() { 19 @Override 20 public void onClick(View arg0) { 21 // TODO Auto-generated method stub 22 TextView tv1 = (TextView) findViewById(R.id.textView1); 23 TextView tv2 = (TextView) findViewById(R.id.textView2); 24 TextView tv3 = (TextView) findViewById(R.id.textView3); 25 26 int a = Integer.parseInt(tv1.getText().toString()); 27 int b = Integer.parseInt(tv2.getText().toString()); 28 TestJni tj = new TestJni(); 29 int c = tj.helloAdd(a,b); 30 String str = tj.helloSay(); 31 tv3.setText(str + Integer.toString(c)); 32 } 33 }); 34 } 35 }
(9)运行AntiVirus工程,在模拟器中可以看到界面输出来自HelloJni.c 文件中的“HelloWorld from JNI ! “。
OK,NDK实例到此完成。后续就可以深入的学习NDK/JNI了,比如C/C++与Java的数据类型转换,Android.mk文件的编写格式等。
标签:android style blog http color io os ar 使用
原文地址:http://www.cnblogs.com/goodhacker/p/4051288.html