Java 中通过jni接口调用native code

 在上上篇中已经介绍了如何编译native code 生成 so动态库,这里再介绍下Java中如何通过JNI接口来调用动态库中的native code方法。
 通过此篇文章,我们可以认识和了解如何完整地在Android的java code中调用native code。
 
1 创建一个 android project, 名字叫Why
 
2 在工程Why中添加一个Java类,class名为Jni。这个类是一个JNI接口的Java类,文件名为Jni.java。  
  package com.yarin.android.Why;
  public class Jni {
         public native int getCInt();
         public native String getCString();
  }
 
3 将工程Why下的 "src\com\yarin\android\Why" 目录下的Jni.java文件copy到“Why\bin\classes”下.
4  Generate Jni.class file via the command below: 
    javac jni.java
    Then copy the Jni.class file generated to cover and replace the original Jni.class file in directory “Why\bin\classes\com\yarin\android\Why”.
     ------The original Jni.class file, you must build the java project first to generate it.
 
5  Generate c style header file
   javah –classpath C:\android-ndk-r6b\myproject\Why\bin\classes  com.yarin.android.Why.Jni
   com.yarin.android.Why is my package name appeared in Jni.java file.
 
com_yarin_android_Why_Jni.h is like below:  
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_yarin_android_Why_Jni */
#ifndef _Included_com_yarin_android_Why_Jni
#define _Included_com_yarin_android_Why_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_yarin_android_Why_Jni
 * Method:    getCInt
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_yarin_android_Why_Jni_getCInt
  (JNIEnv *env, jobject object);   ---you need to supplement the parameter name yourself
/*
 * Class:     com_yarin_android_Why_Jni
 * Method:    getCString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_yarin_android_Why_Jni_getCString
  (JNIEnv *env, jobject object);
#ifdef __cplusplus
}
#endif
#endif
 

6     Add com_yarin_android_Why_Jni.c file corresponding to the above c style header file, then add implemented code.

#include <stdio.h>
#include <stdlib.h>
#include "com_yarin_android_Why_Jni.h"

int add()
{
    int x,y;
    x = 111;
    y = 22;
    x += y;

    return x;
}


JNIEXPORT jint JNICALL Java_com_yarin_android_Why_Jni_getCInt
  (JNIEnv *env, jobject object)
{
    return add();
}

JNIEXPORT jstring JNICALL Java_com_yarin_android_Why_Jni_getCString
  (JNIEnv *env, jobject object)
{
    (*env)->NewStringUTF(env, " Why is ok ^_^ ----->> ");
}

 

7 然后实现在工程Why下创建目录jni,并且copy com_yarin_android_Why_Jni.c /h 到jni目录下。

 

8 在"Why\jni"目录下编写Android.mk ,在"android-ndk-r6b\jni"下编写Application.mk , 然后在NDK环境下编译native code,生成动态库libWhy.so。这个你已经从上上篇中知道的……。

 

9 在java工程中加入调用native 动态库的代码:

package com.yarin.android.Why;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class WhyActivity extends Activity {
 static
 {
  System.loadLibrary("Why");
 }
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Jni jni = new Jni();
        TextView view = new TextView(this);
        view.setText(jni.getCString() + Integer.toString(jni.getCInt()));
        setContentView(view);
    }
}

 

10  编译Why工程,然后 run as Android Application, 你就能看到native code的调用结果了。

Tip:

Usage of the command javah.

javah -d <outputdir> -classpath <classpath> <fully_qualified_class>

where:

'outputdir' is the directory where to put the generated header file

'classpath' contains an absolute path to the directory containing your root package (as mentionned by Glen)

'fully_qualified_class' is the name of the class containing native methods without .class extension

-jni option is not required (set by default)

 

你可能感兴趣的:(java,android,jni,File,Class)