因爲工做須要須要瞭解一下android的ndk開發,就作了一個簡單的例子。java
環境jdk1.6,ndk=android-ndk-r8-windows,eclips3.7,androidsdk=10linux
功能:android的調用一個c99寫的基數排序方法android
工程結構:c++
內容: 紅色部分都是重點windows
編譯一下目的生成HelloJin.clas字節碼文件,個人的工程在D:\lyl_android\因此字節碼文件的絕對路徑在數組
D:\lyl_android\HelloJin\bin\classes\com\example\hellojin目錄下面 app
假使咱們已經配置好了jdk,ndk環境,(這個能夠配好後用相應的命令驗證一下看javah和ndk-build是否能夠用)eclipse
咱們在咱們的工程目錄下創建一個名字叫jni的目錄(即D:\lyl_android\HelloJin\jni)用來存放個人本地化代碼和ide
makefile文件Android.mk(若是想詳細知道makefile是什麼,能夠看看linux)。ui
如今咱們來生成咱們本地化的JNI的頭文件,JNI命名規則手動拼寫容易出錯,咱們藉助JAVAH命令
cmd:打開命令行
D:切換盤符
cd D:\lyl_android\hellojin 進入工程目錄
javah -classpath bin\classess -d jni com.example.hellojin.HelloJin
這個命令的解釋爲:在本工程下bin\classes 目錄下面.class文件中尋找類全名爲com.example.hellojin.HelloJin的類,運行
javah命令生成java本地化的C頭文件com_example_hellojin_HelloJin.h存放在工程目錄下的jni目錄(D:\lyl_android\HelloJin\jni)下。
com_example_hellojin_HelloJin.h的內容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_hellojin_HelloJin */
#ifndef _Included_com_example_hellojin_HelloJin
#define _Included_com_example_hellojin_HelloJin
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_hellojin_HelloJin
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojin_HelloJin_stringFromJNI
(JNIEnv *, jobject);
/*
* Class: com_example_hellojin_HelloJin
* Method: notStringFromJNI
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_hellojin_HelloJin_notStringFromJNI
(JNIEnv *, jobject);
/*
* Class: com_example_hellojin_HelloJin
* Method: radixSort
* Signature: ([II)V
*/
JNIEXPORT void JNICALL Java_com_example_hellojin_HelloJin_radixSort
(JNIEnv *, jobject, jintArray, jint);
#ifdef __cplusplus
}
#endif
#endif
創建一個hello-jni.c的文件,實現com_example_hellojin_HelloJin.h的方法以下所示:
#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojin_HelloJin_stringFromJNI
(JNIEnv * env, jobject jb){
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
/*
* Class: com_example_hellojin_HelloJin
* Method: notStringFromJNI
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_hellojin_HelloJin_notStringFromJNI
(JNIEnv *env, jobject jb){
return ;
}
int data[10]={73, 22, 93, 43, 55, 14, 28, 65, 39, 81}; //待排序的數組
typedef struct list //靜態鏈表結構體類型
{
int data;
int next;
}List;
List bucket[10]; //構造十個桶
List d[10]; //將待排序數據構形成list類型的數組
int maxbit(int data[],int n) //計算待排序數組元數的最長的位數
{
int d=1;
int i=0;
for(;i<n;i++)
{
int c=1;
int p=data[i];
while(p/10)
{
p=p/10;
c++;
}
if(c>d)
d=c;
}
return d;
}
void init(int data[],int n) //清桶的過程,以及將臨時的數組放到d【10】數組中
{
int j=0;
for(j=0;j<n;j++)
{
bucket[j].next=-1;
bucket[j].data=j;
}
for(j=0;j<n;j++)
{
d[j].data=data[j];
d[j].next=-1;
}
}
void RadioSort(int data[],int n) //基數排序的過程
{
int p=maxbit(data,n); //先求出最長的位數
int r=1;
int i=0;
for(;i<p;i++) //執行裝桶倒桶的次數
{
init(data,n); //復位清桶的過程
if(i!=0) //第一次裝桶的時候從小到大開始裝,以後都從大到小裝桶
{ int k=n-1;
for(;k>=0;k--)
{
int a=d[k].data/r;
int b=a%10;
d[k].next=bucket[b].next;
bucket[b].next=k;
}
}
else
{ int k=0;
for(;k<n;k++)
{
int a=d[k].data/r;
int b=a%10;
d[k].next=bucket[b].next;
bucket[b].next=k;
}
}
int c=0;
int k=0;
for(;k<n;k++) //倒桶的過程,將其放到data數組當中
{
if(bucket[k].next!=-1)
{
int p=bucket[k].next;
data[c++]=d[p].data;
while(d[p].next!=-1){
data[c++]=d[d[p].next].data;
p=d[p].next;
}
}
}
r=r*10; //爲了後面對十位數以及高位求當前位置上的數字
}
}
JNIEXPORT void JNICALL Java_com_example_hellojin_HelloJin_radixSort
(JNIEnv * env, jobject jb, jintArray data, jint maxlen){
int size = (*env)->GetArrayLength(env, data);
jint i;
// (*env)->GetIntArrayRegion(data, 0, 10, buf);
jint *buf = (*env)->GetIntArrayElements(env, data, 0 );
RadioSort(buf,size);
/* for (i = 0; i < 10; i++) {
printf("%u",buf[i]);
}*/
(*env)->ReleaseIntArrayElements(env, data, buf, 0);
//env->SetIntArrayRegion(data, 0, 10, buf);
return;
}
在hello-jni.c文件同級目錄中(D:\lyl_android\HelloJin\jni)創建一個名爲Android.mk的文件內容以下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
這個MK文件的具體含義能夠看android ndk文檔,咱們須要改動的地方就包括
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
就能夠了
好如今準備工做已經作好,在cmd下D:\lyl_android\HelloJin目錄下運行命令ndk-build
大功告成,經過eclipse從新編譯android項目搞定;