Android JNI和NDK學習(02)--靜態方式實現JNI

JNI包括兩種實現方法:靜態和動態。兩種方法的區別如下:

靜態:先由Java得到本地方法的聲明,然後再通過JNI實現該聲明方法。

動態:先通過JNI重載JNI_OnLoad()實現本地方法,然後直接在Java中調用本地方法。

 

本文介紹靜態實現方式,下一篇會介紹動態實現方式。

1 首先,在Eclipse下新建一個工程myndk

Myndk.java的代碼如下:

 1 package com.skywang.ndk;
 2  
 3  import android.app.Activity;
 4  import android.os.Bundle;
 5  import android.widget.TextView;
 6  
 7  public class Myndk extends Activity {
 8      
 9      @Override
10      public void onCreate(Bundle savedInstanceState)
11      {
12          super.onCreate(savedInstanceState);
13  
14          TextView  myTextView = new TextView(this);
15          myTextView.setText( HelloNdk() );
16          setContentView(myTextView);
17      }
18  
19      public native String  HelloNdk();
20  
21      static {
22          System.loadLibrary("hello_jni");
23      }
24 }

  

2 運行工程,生成.class文件

檢查bin目錄,若有生成Myndk.class;則繼續下一步。生成.class文件的目的,是爲下一步生成.h頭文件做準備。

 

3 編譯生成.h文件

打開終端,切換到工程所在目錄。假設工程目錄爲“/hom/skywang/workspace/ndk/myndk”,則通過以下命令切換目錄:

$ cd /home/skywang/workspace/ndk/myndk/

查看文件列表

$ ls
$ AndroidManifest.xml  assets  bin  gen  proguard-project.txt  project.properties  res  src

新建jni目錄,並查看文件列表

$ mkdir jni; ls
$ AndroidManifest.xml  assets  bin  gen  jni  proguard-project.txt  project.properties  res  src

生成javah文件

$ javah -classpath bin/classes -d jni com.skywang.ndk.Myndk

-classpath:後面接“類的路徑”。
-d : 後面接“生成的頭文件存放的目錄”,d表示destination。
com.example.hellojni.HelloJni:是完整類名。

上訴命令生成的的.h文件路徑:jni/com_skywang_ndk_Myndk.h 

生成文件內容:

複製代碼
 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2  #include <jni.h>
 3  /* Header for class com_skywang_ndk_Myndk */
 4  
 5  #ifndef _Included_com_skywang_ndk_Myndk
 6  #define _Included_com_skywang_ndk_Myndk
 7  #ifdef __cplusplus
 8  extern "C" {
 9  #endif
10  /*
11   * Class:     com_skywang_ndk_Myndk
12   * Method:    HelloNdk
13   * Signature: ()Ljava/lang/String;
14   */
15  JNIEXPORT jstring JNICALL Java_com_skywang_ndk_Myndk_HelloNdk
16    (JNIEnv *, jobject);
17  
18  #ifdef __cplusplus
19  }
20  #endif
21  #endif
複製代碼

  

補充:若執行javah命令時,遇到如下錯誤。是因爲-classpath後面所接的路徑不對!

error: cannot access com.skywang.ndk.Myndk
class file for com.skywang.ndk.Myndk not found
javadoc: error - Class com.skywang.ndk.Myndk not found.
Error: No classes were specified on the command line. Try -help.

 

有了com_skywang_ndk_Myndk.h頭文件之後,我們就可以實現該頭文件中聲明的函數。

 

4 實現頭文件中聲明的函數

新建文件jni/hello_jni.c。hello_jni.c的代碼如下:

複製代碼
#include <string.h>
#include <jni.h>
 
JNIEXPORT jstring JNICALL Java_com_skywang_ndk_Myndk_HelloNdk
  (JNIEnv* env, jobject obj)
{
    return (*env)->NewStringUTF(env, "Hello JNI!");
}
複製代碼

 

 hello_jni.c的作用就是實現com_skywang_ndk_Myndk.h中聲明的函數。

 

5 編寫實現函數對應的Android.mk

添加文件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)
複製代碼

  

6 編譯生成庫文件

進入到工程所在目錄,執行ndk-build,編譯生成.so庫文件。

$ cd /home/skywang/workspace/ndk/myndk/
$ ndk-build

 生成庫文件所在目錄:libs/armeabi/libhello_jni.so

 

7 重新運行工程

重新運行eclipse下的myndk工程。輸出如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章