在Native中調用java層的函數
Java層
JniHandler.java
1.調用私有函數輸出信息
@Keep
private void updateStatus(String msg) {
if (msg.toLowerCase().contains("error")) {
Log.e("JniHandler", "Native Err: " + msg);
} else {
Log.i("JniHandler", "Native Msg: " + msg);
}
}
2.獲取當前android系統的版本
@Keep
static public String getBuildVersion() {
return Build.VERSION.RELEASE;
}
3.獲取android系統運行時閒置的內存空間大小
@Keep
public long getRuntimeMemorySize() {
return Runtime.getRuntime().freeMemory();
}
Native層
由於只是調用這些函數來獲取相應的信息因此可以都在
JNI_OnLoad()函數中獲取並調用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
//將結構體所在內存的每個字節的內容設置爲0;
memset(&g_ctx, 0, sizeof(g_ctx));
//爲結構體的javaVm賦值
g_ctx.javaVM = vm;
//拿到該線程的JNIEnv*結構體存入env中
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
//////////////
jclass clz=(*env)->FindClass(env,
"com/wbl/ndktest/JniHandler");
//引用這個JniHandler類
g_ctx.jniHelperClz=(*env)->NewGlobalRef(env,clz);
//查找init的方法
jmethodID jniHelperCtor=(*env)->GetMethodID(env,g_ctx.jniHelperClz,"<init>","()V");
//新建一個jniHandler對象
jobject handler=(*env)->NewObject(env,g_ctx.jniHelperClz,jniHelperCtor);
//引用這個對象
g_ctx.jniHelperObj=(*env)->NewGlobalRef(env,handler);
//找到updateStatus方法.
jmethodID updateStatus=(*env)->GetMethodID(env,g_ctx.jniHelperClz,"updateStatus","(Ljava/lang/String;)V");
sendJavaMsg(env,g_ctx.jniHelperObj,updateStatus,"Hello EveryOne");
queryRuntimeInfo(env,g_ctx.jniHelperObj);
return JNI_VERSION_1_6;
}
//調用updateStatus方法 發送一個消息
void sendJavaMsg(JNIEnv *env,jobject instance,
jmethodID func,const char* msg){
//獲得一個jstring的對象
jstring javaMsg=(*env)->NewStringUTF(env,msg);
//調用updateStatus方法,將jstring作爲參數傳入
(*env)->CallVoidMethod(env,instance,func,javaMsg);
//刪除javaMsg的引用
(*env)->DeleteLocalRef(env,javaMsg);
}
//調用java層的getBuildVersion()函數來獲取Android系統的版本
//調用java層的getRuntimeMemorySize()函數來獲取當前系統運行時內存閒置的空間大小
JNIEXPORT void queryRuntimeInfo(JNIEnv *pInterface, jobject pVoid) {
//查找到getBuildVersion()方法
jmethodID versionFunc=(*pInterface)->GetStaticMethodID(pInterface,g_ctx.jniHelperClz,
"getBuildVersion","()Ljava/lang/String;");
//調用方法獲取到版本號
jstring buildVersion=(*pInterface)->CallStaticObjectMethod(pInterface,g_ctx.jniHelperClz,
versionFunc);
//將jstring的字符串轉換爲char*類型的字符串
const char *version=(*pInterface)->GetStringUTFChars(pInterface,buildVersion,NULL);
//在log中輸出版本信息
LOGI("version %s",version);
//釋放jstring類型的變量
(*pInterface)->ReleaseStringUTFChars(pInterface,buildVersion,version);
//刪除本地引用
(*pInterface)->DeleteLocalRef(pInterface,buildVersion);
//查找getRuntimeMemorySize()函數
jmethodID memFunc=(*pInterface)->GetMethodID(pInterface,g_ctx.jniHelperClz,"getRuntimeMemorySize","()J");
//調用該函數獲取內存閒置空間大小
jlong result=(*pInterface)->CallLongMethod(pInterface,pVoid,memFunc);
//輸出內存閒置空間大小
LOGI("Runtime free memory size: %lld", result);
(void)result;
}
在代碼中出現了一個LOGI函數 這是宏定義的一個函數用於簡化在android中輸入log信息的參數設置
//需要先引入頭文件
#include <android/log.h>
//設置宏定義
#define LOGI(...) \
((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
還需要在 module:app的build.gradle的ndk標籤中加入庫的引用
ndk{
moduleName='wbl-jni'
toolchain= 'clang'
CFlags.addAll(['-Wall'])
ldLibs.addAll(['android','log']) //多了這句
}