使用JNI在C中調用java代碼

使用JNI在C中調用java代碼
1.定義個類來定義java的native方法
public class DataProvider {
static{
System.loadLibrary("Hello");
}
public native void callCcode();
public native void callCcode2();
public native void callCcode3();
//C調用java空方法
public void helloFromJava(){
System.out.println("hello from java");
}
//C調用java中的帶兩個int參數的方法
public static int Add(int x,int y){
System.out.println("java "+ (x+y));
return x+y;
}
//C調用java中參數爲string的方法
public void printString(String s){
System.out.println("java "+ s);
}
 }
2.用javah編譯那個native的類.
3.新建jni的文件夾.把剛剛編譯生成的.h的頭文件給拷貝進來.
4.在jni的文件夾下新建XX.c文件
5.編寫c代碼
#include <stdio.h>
#include <jni.h>
#include "com_mccxxiv_ndk4_DemoActivity.h"
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
JNIEXPORT void JNICALL Java_com_mccxxiv_ndk4_DataProvider_callCcode
  (JNIEnv * env, jobject obj){
 // new 出來java的對象 然後調用java對象裏面的方法
char* classname = "com/mccxxiv/ndk4/DataProvider";
jclass clazz; //定義一個java中的類
clazz = (*env)->FindClass(env,classname); //該方法返回一個類
if(clazz==0){
LOGI("CAN'T FIND CLAZZ ");
}else{
LOGI("FIND CLASS");
}
//該方法返回指定類中的指定方法
//最後一個參數是方法的簽名.
//獲取方法的簽名是用dos進到工程的classes目錄下用javap -s 包名+類名
jmethodID java_method = (*env)->GetMethodID(env,clazz,"helloFromJava","()V");
if(java_method==0){
LOGI("CAN'T FIND java_method ");
}else{
LOGI("FIND java_method");
}
//調用java中無返回值的方法.第二個參數obj爲類的對象.
//所以把native的方法放到和方法在同一個類中(DataProvider)
//如果native方法和c要調用的java方法不在同一個類中.在c代碼中需調用AllocObject()方法來手動的指定obj對象
//方法的返回值不同調用的CallXXXMethod中的XXX不同.返回值是什麼類型XXX就是什麼.
//靜態的方法也是一樣的.XXX就是StaticXXX.少一個obj的參數.
(*env)->CallVoidMethod(env,obj,java_method);
}

JNIEXPORT void JNICALL Java_com_mccxxiv_ndk4_DataProvider_callCcode2
  (JNIEnv * env, jobject obj){
char* classname = "com/mccxxiv/ndk4/DataProvider";
jclass clazz;
clazz = (*env)->FindClass(env,classname);
if(clazz==0){
LOGI("CAN'T FIND CLAZZ ");
}else{
LOGI("FIND CLASS");
}
jmethodID java_method = (*env)->GetMethodID(env,clazz,"Add","(II)I");
if(java_method==0){
LOGI("CAN'T FIND java_method ");
}else{
LOGI("FIND java_method");
}
jint result = (*env)->CallIntMethod(env,obj,java_method,5,8);
LOGI("c daima  %d",result);
}

JNIEXPORT void JNICALL Java_com_mccxxiv_ndk4_DataProvider_callCcode3
  (JNIEnv * env, jobject obj){
char* classname = "com/mccxxiv/ndk4/DataProvider";
jclass clazz;
clazz = (*env)->FindClass(env,classname);
if(clazz==0){
LOGI("CAN'T FIND CLAZZ ");
}else{
LOGI("FIND CLASS");
}
jmethodID java_method = (*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V");
if(java_method==0){
LOGI("CAN'T FIND java_method ");
}else{
LOGI("FIND java_method");
}
(*env)->CallVoidMethod(env,obj,java_method,(*env)->NewStringUTF(env,"haha from c"));
 }
6.在jni文件夾下新建Android.mk文件
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS) #類似於工具初始化的操作 

LOCAL_MODULE    := Hello
LOCAL_SRC_FILES := Hello.c

LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY) 
7.用ndk-build命令編譯
8.在主Activity中調用native方法
   public class DemoActivity extends Activity {
   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);    
    }
    
    public void click(View view){
     DataProvider provider = new DataProvider();
     provider.callCcode();
    }
    public void click2(View view){
     DataProvider provider = new DataProvider();
     provider.callCcode2();
    }
    public void click3(View view){
     DataProvider provider = new DataProvider();
     provider.callCcode3();
    }
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章