android ndk 基數排序

因爲工做須要須要瞭解一下android的ndk開發,就作了一個簡單的例子。java

環境jdk1.6,ndk=android-ndk-r8-windows,eclips3.7,androidsdk=10linux

功能:android的調用一個c99寫的基數排序方法android

工程結構:c++

內容: 紅色部分都是重點windows

  1. package com.example.hellojin;
  2. import android.annotation.SuppressLint;
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.Menu;
  6. import android.widget.TextView;
  7. public class HelloJin extends Activity {
  8.     @Override
  9.     public void onCreate(Bundle savedInstanceState) {
  10.         super.onCreate(savedInstanceState);
  11.         TextView  tv = new TextView(this);
  12.         int[] data={3, 22, 93, 43, 55, 14, 28, 64, 88, 81};
  13.         //"排序以前的數值:";
  14.         StringBuffer stringBuffer=new StringBuffer("排序以前的數值\r\n");
  15.         for(int i=0;i<10;i++){
  16.             stringBuffer.append(data[i]+",");
  17.         }
  18.        
  19.         radixSort(data,10);
  20.         stringBuffer.append("排序以後的數值:\r\n");
  21.         for(int i=0;i<10;i++)
  22.             stringBuffer.append(data[i]+",");
  23.         tv.setText( stringFromJNI()+stringBuffer );
  24.         setContentView(tv);
  25.       //  setContentView(R.layout.activity_hello_jin);
  26.     }
  27.    
  28.     public native String stringFromJNI();
  29.    
  30.     public native void notStringFromJNI();
  31.     //基數排序
  32.     public native void radixSort(int[] array ,int maxLength);
  33.     @Override
  34.     public boolean onCreateOptionsMenu(Menu menu) {
  35.         getMenuInflater().inflate(R.menu.activity_hello_jin, menu);
  36.         return true;
  37.     }
  38.     static {
  39.         System.loadLibrary("hello-jni");
  40.     }
  41. }

編譯一下目的生成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項目搞定;

相關文章
相關標籤/搜索