c調用java
阿新 • • 發佈:2017-05-23
lint n) ges file adl med blog 由於 machine
public class MainActivity extends AppCompatActivity { private JNI jni; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); jni = new JNI(); } public void test1(View v){ jni.callVoid(); }public void test2(View v){ jni.callInt(); } public void test3(View v){ jni.callString(); } public void test4(View v){ //jni.callShowToast(); callShowToast(); } public void showToast(String s){ Toast.makeText(this, s, Toast.LENGTH_SHORT).show(); }public native void callShowToast(); }
public class JNI { static { System.loadLibrary("ccalljava"); } // C調用java空方法 public void helloFromJava(){ Log.e("calljava","hello from java"); } // C調用java中的帶兩個int參數的方法 public int add(int x,int y) { return x+y; }// C調用java中參數為string的方法 public void printString(String s){ Log.e("calljava",s); } public native void callVoid(); public native void callInt(); public native void callString(); public native void callShowToast(); }
上面圖片是下面代碼的標題
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_itheima_ccalljava_JNI */ #ifndef _Included_com_itheima_ccalljava_JNI #define _Included_com_itheima_ccalljava_JNI #ifdef __cplusplus extern "C" { #endif /* * Class: com_itheima_ccalljava_JNI * Method: callVoid * Signature: ()V */ JNIEXPORT void JNICALL Java_com_itheima_ccalljava_JNI_callVoid (JNIEnv *, jobject); /* * Class: com_itheima_ccalljava_JNI * Method: callInt * Signature: ()V */ JNIEXPORT void JNICALL Java_com_itheima_ccalljava_JNI_callInt (JNIEnv *, jobject); /* * Class: com_itheima_ccalljava_JNI * Method: callString * Signature: ()V */ JNIEXPORT void JNICALL Java_com_itheima_ccalljava_JNI_callString (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
Android.mk文件:下面
# Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #LOCAL_PATH 獲取當前路徑 LOCAL_PATH := $(call my-dir) # 清除上次編譯獲取的編譯環境變量 會保存LOCAL_PATH include $(CLEAR_VARS) #指定編譯生成的模塊叫什麽名字 生成的.so名字會加上lib前綴和.so後綴 LOCAL_MODULE := ccalljava #指定要編譯的.c源文件叫什麽名字 LOCAL_SRC_FILES := ccalljava.c LOCAL_LDLIBS += -llog #生成動態鏈接庫 .so文件 include $(BUILD_SHARED_LIBRARY)
#include <jni.h> // Created by fullcircle on 2017/2/19. // #include <android/log.h> #define LOG_TAG "System.out" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callVoid (JNIEnv * env, jobject thiz){ //①找到字節碼對象 Class jclass (*FindClass)(JNIEnv*, const char*); //第二個參數 要找到的字節碼的全類名 jclass clazz = (*env)->FindClass(env,"com/zz/ccalljava/JNI"); //②在Class 中找到要調用的方法 Method //jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); //GetMethodID 第二個參數 clazz字節碼對象 第三個參數方法的名字 第四個參數 方法簽名 可以通過javap -s 獲取 //在Studio中到模塊的 build/intermediates/classes/debug 執行javap -s 要生成方法簽名的類的全路徑 jmethodID methodID = (*env)->GetMethodID(env,clazz,"helloFromJava","()V"); //③通過Class獲取對象(有時可以省略 當native方法和要回調的java方法在同一個類中就可以使用傳過來的jobject調用方法) //④通過對象調用方法 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); (*env)->CallVoidMethod(env,thiz,methodID); } /* * Class: com_zz_ccalljava_JNI * Method: callInt * Signature: ()V */ JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callInt (JNIEnv * env, jobject thiz){ //①找到class jclass clazz =(*env)->FindClass(env,"com/zz/ccalljava/JNI"); //②找到方法 jmethodID methodID = (*env)->GetMethodID(env,clazz,"add","(II)I"); //③調用方法 int result = (*env)->CallIntMethod(env,thiz,methodID,3,4); LOGE("result=%d",result); } /* * Class: com_zz_ccalljava_JNI * Method: callString * Signature: ()V */ JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callString (JNIEnv * env, jobject thiz){ jclass clazz = (*env)->FindClass(env,"com/zz/ccalljava/JNI"); jmethodID methodID=(*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V"); jstring jstr = (*env)->NewStringUTF(env,"hello from c"); (*env)->CallVoidMethod(env,thiz,methodID,jstr); } JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callShowToast (JNIEnv * env, jobject thiz){ jclass clazz =(*env)->FindClass(env,"com/zz/ccalljava/MainActivity"); jmethodID methodID = (*env)->GetMethodID(env,clazz,"showToast","(Ljava/lang/String;)V"); //由於callShowToast這個native方法是在 jni這個類中 要調用的java方法是在MainActivity中 所以不能使用傳入的jobject //需要創建一個對象 jobject (*AllocObject)(JNIEnv*, jclass); jobject jobj =(*env)->AllocObject(env,clazz); jstring jstr = (*env)->NewStringUTF(env,"hello from c"); (*env)->CallVoidMethod(env,jobj,methodID,jstr); } JNIEXPORT void JNICALL Java_com_zz_ccalljava_MainActivity_callShowToast (JNIEnv * env, jobject thiz){ jclass clazz =(*env)->FindClass(env,"com/zz/ccalljava/MainActivity"); jmethodID methodID = (*env)->GetMethodID(env,clazz,"showToast","(Ljava/lang/String;)V"); //由於callShowToast這個native方法是在 jni這個類中 要調用的java方法是在MainActivity中 所以不能使用傳入的jobject //需要創建一個對象 jobject (*AllocObject)(JNIEnv*, jclass); // jobject jobj =(*env)->AllocObject(env,clazz); jstring jstr = (*env)->NewStringUTF(env,"hello from c"); (*env)->CallVoidMethod(env,thiz,methodID,jstr); }
c調用java