#include <jni.h> #include <string> #include <android/log.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; LOGD("DEBUG"); LOGI("INFO"); LOGE("ERROR"); return env->NewStringUTF(hello.c_str()); } 複製代碼
#include <jni.h> #include <string> #include <android/log.h> #include <pthread.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); void* test(void* arg){ for (int i = 0; i < 10; ++i) { LOGD("i=%d", i); } pthread_exit(0); } extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; pthread_t thread; pthread_create(&thread, NULL, test, NULL); pthread_join(thread, nullptr); return env->NewStringUTF(hello.c_str()); } 複製代碼
#include <jni.h> #include <string> #include <android/log.h> #include <pthread.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); void* test(void* arg){ for (int i = 0; i < *(int*)arg; ++i) { LOGD("%d i=%d", *(int*)arg, i); } pthread_exit(0); } extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; pthread_t thread; int num = 11; pthread_create(&thread, NULL, test, &num); pthread_join(thread, nullptr); return env->NewStringUTF(hello.c_str()); } 複製代碼
#include <jni.h> #include <string> #include <android/log.h> #include <pthread.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); struct node{ int num; std::string str; }; void* test(void* arg){ struct node* p = (struct node*)arg; for (int i = 0; i < p->num; ++i) { LOGD("%d i=%d", p->num, i); } LOGD("%s", (p->str).c_str()) pthread_exit(0); } extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; pthread_t thread; int num = 11; struct node abc; abc.num = 18; abc.str = "xty"; pthread_create(&thread, NULL, test, &abc); pthread_join(thread, nullptr); return env->NewStringUTF(hello.c_str()); } 複製代碼
#include <jni.h> #include <string> #include <android/log.h> #include <pthread.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); typedef struct { int num; std::string str; } node; void* test(void* arg) { node *p = (node *) arg; for (int i = 0; i < p->num; ++i) { LOGD("%d i=%d", p->num, i); } LOGD("%s", (p->str).c_str()) pthread_exit(0); } extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; pthread_t thread; int num = 11; node abc; abc.num = 18; abc.str = "xty"; pthread_create(&thread, NULL, test, &abc); pthread_join(thread, nullptr); return env->NewStringUTF(hello.c_str()); } 複製代碼
獲取JavaVM的幾種方式 JNI_OnLoad JNI_OnUnload env->GetJavaVMjava
獲取JNIEnv的幾種方式 函數靜態註冊傳參 vm->GetEnv globalVM->AttachCurrentThreadnode
JNI_OnLoad 必須返回JNI版本 JNI_VERSION_1_6 對比各類方式獲取的JavaVM與JNIEnv指針是否一致android
進程中只有一個JavaVM,但能夠有多個JNIEnvc++
#include <jni.h> #include <string> #include <android/log.h> #include <pthread.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); JavaVM *globalVM = nullptr; typedef struct { int num; std::string str; } node; void *test(void *arg) { node *p = (node *) arg; for (int i = 0; i < p->num; ++i) { LOGD("%d i=%d", p->num, i); } LOGD("%s", (p->str).c_str()) pthread_exit(0); } extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; JavaVM* vm; env->GetJavaVM(&vm); LOGD("GetJavaVM %p", vm); LOGD("Java_com_example_cdemo_MainActivity_stringFromJNI JNIEnv %p", env); pthread_t thread; node abc; abc.num = 18; abc.str = "xty"; pthread_create(&thread, NULL, test, &abc); pthread_join(thread, nullptr); return env->NewStringUTF(hello.c_str()); } void *myThread(void *args) { JNIEnv *myThreadEnv = nullptr; if (globalVM->GetEnv((void **) &myThreadEnv, JNI_VERSION_1_6) == JNI_OK) { LOGD("globalVM->GetEnv success"); LOGD("globalVM->GetEnv JNIEnv %p", myThreadEnv); } else { LOGD("globalVM->GetEnv failed"); } if (globalVM->AttachCurrentThread(&myThreadEnv, nullptr) == JNI_OK){ LOGD("globalVM->AttachCurrentThread success"); LOGD("globalVM->AttachCurrentThread JNIEnv %p", myThreadEnv); }else { LOGD("globalVM->AttachCurrentThread failed"); } globalVM->DetachCurrentThread(); pthread_exit(0); } JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { globalVM = vm; LOGD("JNI_OnLoad JavaVM %p", vm); JNIEnv *env = nullptr; if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { LOGD("GetEnv failed"); return -1; } LOGD("JNI_OnLoad JNIEnv %p", env); pthread_t thread; pthread_create(&thread, nullptr, myThread, nullptr); pthread_join(thread, nullptr); LOGD("線程結束"); return JNI_VERSION_1_6; } 複製代碼
#include <jni.h> #include <string> #include <android/log.h> #include <pthread.h> #define TAG "XTY_NDK" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__); #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__); JavaVM *globalVM = nullptr; extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } void *myThread(void *args) { JNIEnv *myThreadEnv = nullptr; if (globalVM->GetEnv((void **) &myThreadEnv, JNI_VERSION_1_6) == JNI_OK) { LOGD("globalVM->GetEnv success"); LOGD("globalVM->GetEnv JNIEnv %p", myThreadEnv); } else { LOGD("globalVM->GetEnv failed"); } if (globalVM->AttachCurrentThread(&myThreadEnv, nullptr) == JNI_OK){ LOGD("globalVM->AttachCurrentThread success"); LOGD("globalVM->AttachCurrentThread JNIEnv %p", myThreadEnv); }else { LOGD("globalVM->AttachCurrentThread failed"); } jclass TestJclass = nullptr; TestJclass = myThreadEnv->FindClass("com/xty/Cdemo/ReflectDemo"); myThreadEnv->ExceptionDescribe(); myThreadEnv->ExceptionClear(); if (TestJclass == nullptr) { LOGD("myThreadEnv->FindClass failed"); }; globalVM->DetachCurrentThread(); pthread_exit(0); } JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { globalVM = vm; JNIEnv *env = nullptr; if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { LOGD("GetEnv failed"); return -1; } pthread_t thread; pthread_create(&thread, nullptr, myThread, nullptr); pthread_join(thread, nullptr); LOGD("線程結束"); return JNI_VERSION_1_6; } 複製代碼
#include <jni.h> JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv* env, jobject obj /* this */) { char* hello = "Hello from C++"; return (*env)->NewStringUTF(env, hello); } 複製代碼
__int64 __fastcall Java_com_xiaojianbang_demo2_MainActivity_stringFromJNI(_JNIEnv *a1) { return ((__int64 (__fastcall *)(_JNIEnv *, const char *))a1->functions->NewStringUTF)(a1, "Hello from C++"); } 複製代碼
#include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_example_cdemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } 複製代碼
int __fastcall Java_com_xiaojianbang_demo_MainActivity_stringFromJNI(_JNIEnv *a1) { _JNIEnv *v1; // ST24_4 const char *v2; // r0 int result; // r0 int v4; // [sp+0h] [bp-40h] char v5; // [sp+28h] [bp-18h] int v6; // [sp+34h] [bp-Ch] v1 = a1; sub_8E60(); v2 = (const char *)sub_8EC2((int)&v5); v4 = _JNIEnv::NewStringUTF(v1, v2); std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v5); result = _stack_chk_guard; if ( _stack_chk_guard == v6 ) result = v4; return result; } 複製代碼
jstring encodeFromC(JNIEnv* env, jobject obj, jint a, jstring b, jbyteArray jbt){ return env->NewStringUTF("this string from cpp"); } JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { globalVM = vm; JNIEnv *env = nullptr; if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { LOGD("GetEnv failed"); return -1; } auto clazz = env->FindClass("com/example/demo/MainActivity"); JNINativeMethod methods[] = { //public native String encode(int i, String str, byte[] byt); {"encode", "(ILjava/lang/String;[B)Ljava/lang/String;", (void *)encodeFromC} }; env->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(JNINativeMethod)); return JNI_VERSION_1_6; } 複製代碼
package com.example.demo; import android.util.Log; public class ExampleClass { public static String publicStaticStringField = "this is publicStaticStringField"; public String publicStringField = "this is publicStringField"; private static String privateStaticStringField = "this is privateStaticStringField"; private String privateStringField = "this is privateStringField"; public ExampleClass(){ Log.d("example", "this is ExampleClass()"); } public ExampleClass(String str){ Log.d("example", "this is ExampleClass(String str)"); } public ExampleClass(String str, int i){ Log.d("example", i + " " + str); Log.d("example", "this is ExampleClass(String str, int i)"); } public static void publicStaticFunc(){ Log.d("example", "this is publicStaticFunc"); } public void publicFunc(){ Log.d("example", "this is publicFunc"); } private static void privateStaticFunc(){ Log.d("example", "this is privateStaticFunc"); } private void privateFunc(){ Log.d("example", "this is privateFunc"); } } 複製代碼
jstring encodeFromC(JNIEnv* env, jobject obj, jint a, jstring b, jbyteArray jbt){ //NewObject建立對象 auto clazz = env->FindClass("com/example/demo/ExampleClass"); auto methodID = env->GetMethodID(clazz, "<init>", "()V"); auto ExampleClassObj = env->NewObject(clazz, methodID); LOGD("ExampleClassObj %p", ExampleClassObj); return env->NewStringUTF("this string from cpp"); } 複製代碼
jstring encodeFromC(JNIEnv* env, jobject obj, jint a, jstring b, jbyteArray jbt){ //AllocObject建立對象 auto clazz = env->FindClass("com/example/demo/ExampleClass"); auto methodID = env->GetMethodID(clazz, "<init>", "()V"); auto ExampleClassObj = env->AllocObject(clazz); env->CallNonvirtualVoidMethod(ExampleClassObj, clazz, methodID); return env->NewStringUTF("this string from cpp"); } 複製代碼
jstring encodeFromC(JNIEnv* env, jobject obj, jint a, jstring b, jbyteArray jbt){ auto clazz = env->FindClass("com/example/demo/ExampleClass"); //獲取靜態字段 auto privateStaticStringField = env->GetStaticFieldID(clazz, "privateStaticStringField", "Ljava/lang/String;"); jstring privateStaticString = static_cast<jstring>(env->GetStaticObjectField(clazz, privateStaticStringField)); const char* privatecstr = env->GetStringUTFChars(privateStaticString, nullptr); LOGD("privateStaticString: %s", privatecstr); return env->NewStringUTF("this string from cpp"); } 複製代碼
jstring encodeFromC(JNIEnv* env, jobject obj, jint a, jstring b, jbyteArray jbt){ auto clazz = env->FindClass("com/example/demo/ExampleClass"); auto ExampleClassObj = env->AllocObject(clazz); //獲取對象字段 auto publicStringField = env->GetFieldID(clazz, "publicStringField", "Ljava/lang/String;"); jstring publicString = static_cast<jstring>(env->GetObjectField(ExampleClassObj, publicStringField)); const char* publiccstr = env->GetStringUTFChars(publicString, nullptr); LOGD("publicStringField: %s", publiccstr); return env->NewStringUTF("this string from cpp"); } 複製代碼
jstring encodeFromC(JNIEnv* env, jobject obj, jint a, jstring b, jbyteArray jbt){ //NewObject建立對象 auto clazz = env->FindClass("com/example/demo/ExampleClass"); auto methodID = env->GetMethodID(clazz, "<init>", "()V"); auto ExampleClassObj = env->NewObject(clazz, methodID); LOGD("ExampleClassObj %p", ExampleClassObj); //獲取數組字段ID auto byteArrayID = env->GetFieldID(clazz, "byteArray", "[B"); jbyteArray byteArray = static_cast<jbyteArray>(env->GetObjectField(ExampleClassObj, byteArrayID)); int _byteArrayLength = env->GetArrayLength(byteArray); //修改數組字段 char javaByte[10]; for(int i = 0; i < 10; i++){ javaByte[i] = static_cast<char>(100 - i); } const jbyte *java_array = reinterpret_cast<const jbyte *>(javaByte); env->SetByteArrayRegion(byteArray, 0, _byteArrayLength, java_array); //獲取數組字段 byteArray = static_cast<jbyteArray>(env->GetObjectField(ExampleClassObj, byteArrayID)); _byteArrayLength = env->GetArrayLength(byteArray); char* str = reinterpret_cast<char *>(env->GetByteArrayElements(byteArray, nullptr)); for(int i = 0; i< _byteArrayLength; i++){ LOGD("str[%d]=%d", i, str[i]); } return env->NewStringUTF("this string from cpp"); } 複製代碼
//public native String encodeB(int i, String str, byte[] byt); extern "C" JNIEXPORT jstring JNICALL Java_com_example_demo_MainActivity_encodeB( JNIEnv* env, jobject /* this */, jint a, jstring b, jbyteArray c) { //一、調用靜態函數 jclass ExampleClassClazz = env->FindClass("com/example/demo/ExampleClass"); jmethodID publicStaticFuncID = env->GetStaticMethodID(ExampleClassClazz, "publicStaticFunc", "()V"); env->CallStaticVoidMethod(ExampleClassClazz, publicStaticFuncID); return env->NewStringUTF(""); } 複製代碼
//public native String encodeB(int i, String str, byte[] byt); extern "C" JNIEXPORT jstring JNICALL Java_com_example_demo_MainActivity_encodeB( JNIEnv* env, jobject /* this */, jint a, jstring b, jbyteArray c) { //二、調用對象函數 jclass ExampleClassClazz = env->FindClass("com/example/demo/ExampleClass"); jmethodID privateFuncID = env->GetMethodID(ExampleClassClazz, "privateFunc", "(Ljava/lang/String;I)Ljava/lang/String;"); jmethodID ExampleClassInit = env->GetMethodID(ExampleClassClazz, "<init>", "(Ljava/lang/String;)V"); jstring str1 = env->NewStringUTF("this is from NDK"); jobject ExampleClassObj = env->NewObject(ExampleClassClazz, ExampleClassInit, str1); jstring str2 = env->NewStringUTF("this is from JNI"); jstring retval = static_cast<jstring>(env->CallObjectMethod(ExampleClassObj, privateFuncID, str2, 1000)); const char* cpp_retval = env->GetStringUTFChars(retval, nullptr); LOGD("cpp_retval: %s", cpp_retval); env->ReleaseStringUTFChars(retval, cpp_retval); return env->NewStringUTF(""); } 複製代碼
//public native String encodeB(int i, String str, byte[] byt); extern "C" JNIEXPORT jstring JNICALL Java_com_example_demo_MainActivity_encodeB( JNIEnv* env, jobject /* this */, jint a, jstring b, jbyteArray c) { jclass ExampleClassClazz = env->FindClass("com/example/demo/ExampleClass"); jmethodID privateFuncID = env->GetMethodID(ExampleClassClazz, "privateFunc", "(Ljava/lang/String;I)Ljava/lang/String;"); jmethodID ExampleClassInit = env->GetMethodID(ExampleClassClazz, "<init>", "(Ljava/lang/String;)V"); jstring str1 = env->NewStringUTF("this is from NDK"); jobject ExampleClassObj = env->NewObject(ExampleClassClazz, ExampleClassInit, str1); jstring str2 = env->NewStringUTF("this is from JNI"); jvalue args[2]; args[0].l = str2; args[1].i = 1000; jstring retval = static_cast<jstring>(env->CallObjectMethodA(ExampleClassObj, privateFuncID, args)); const char* cpp_retval = env->GetStringUTFChars(retval, nullptr); LOGD("cpp_retval: %s", cpp_retval); env->ReleaseStringUTFChars(retval, cpp_retval); return env->NewStringUTF(""); } 複製代碼
//public native String encodeB(int i, String str, byte[] byt); extern "C" JNIEXPORT jstring JNICALL Java_com_xiaojianbang_demo_MainActivity_encodeB( JNIEnv* env, jobject /* this */, jint a, jstring b, jbyteArray c) { jclass ExampleClassClazz = env->FindClass("com/example/demo/ExampleClass"); // 參數是數組 返回值是數組 //private static int[] privateStaticFunc(String[] str) jclass StringClazz = env->FindClass("java/lang/String"); jobjectArray StringArr = env->NewObjectArray(3, StringClazz, nullptr); for(int i = 0; i < 3; i++){ jstring str3 = env->NewStringUTF("NDK"); env->SetObjectArrayElement(StringArr, i, str3); } jmethodID privateStaticFuncID = env->GetStaticMethodID(ExampleClassClazz, "privateStaticFunc", "([Ljava/lang/String;)[I"); jintArray intArr = static_cast<jintArray>(env->CallStaticObjectMethod(ReflectDemoClazz, privateStaticFuncID, StringArr)); int *cintArr = env->GetIntArrayElements(intArr, nullptr); LOGD("cintArr[0]=%d", cintArr[0]); //三、調用父類函數 return env->NewStringUTF(""); } 複製代碼
extern "C" JNIEXPORT void JNICALL Java_com_xiaojianbang_demo_MainActivity_onCreate(JNIEnv *env, jobject thiz, jobject saved_instance_state) { //調用父類函數 jclass AppCompatActivityClazz = env->FindClass("androidx/appcompat/app/AppCompatActivity"); jmethodID onCreateID = env->GetMethodID(AppCompatActivityClazz, "onCreate", "(Landroid/os/Bundle;)V"); env->CallNonvirtualVoidMethod(thiz, AppCompatActivityClazz, onCreateID, saved_instance_state); } 複製代碼
package com.example.demo; import androidx.appcompat.app.AppCompatActivity; import android.app.Activity; import android.app.Application; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements OnClickListener { // Used to load the 'native-lib' library on application startup. String nativePathA = null; String nativePathB = null; static { System.loadLibrary("exampleA"); System.loadLibrary("exampleB"); } @Override protected native void onCreate(Bundle savedInstanceState); // protected void onCreate(Bundle savedInstanceState) { // super.onCreate(savedInstanceState); // // setContentView(R.layout.activity_main); // TextView tv = findViewById(R.id.sample_text); // // nativePathA = new Utils().getPath(getApplicationContext()) + "/libexampleA.so"; // nativePathB = new Utils().getPath(getApplicationContext()) + "/libexampleB.so"; // getApplicationContext(); // tv.setText(stringFromJNIA(nativePathB)); // stringFromJNIB(nativePathA); // // Log.d("example", encode(100, "example", new byte[]{49,50,51,52,53,54,55,56,57,58,59})); // Log.d("example", encodeB(100, "example", new byte[]{49,50,51,52,53,54,55,56,57,58,59})); // // findViewById(R.id.button).setOnClickListener(this); // } public void onClick(View v) { stringFromJNIA(nativePathB); } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNIA(String str); public native String stringFromJNIB(String str); public native String encode(int i, String str, byte[] byt); public native String encodeB(int i, String str, byte[] byt); } 複製代碼
extern "C" JNIEXPORT void JNICALL Java_com_xiaojianbang_demo_MainActivity_onCreate(JNIEnv *env, jobject thiz, jobject saved_instance_state) { //super.onCreate(savedInstanceState); jclass AppCompatActivityClazz = env->FindClass("androidx/appcompat/app/AppCompatActivity"); jmethodID onCreateID = env->GetMethodID(AppCompatActivityClazz, "onCreate", "(Landroid/os/Bundle;)V"); env->CallNonvirtualVoidMethod(thiz, AppCompatActivityClazz, onCreateID, saved_instance_state); //R.layout.activity_main jclass R$layoutClazz = env->FindClass("com/example/demo/R$layout"); jfieldID activity_mainID = env->GetStaticFieldID(R$layoutClazz, "activity_main", "I"); int activity_mainValue = env->GetStaticIntField(R$layoutClazz, activity_mainID); LOGD("activity_mainValue=%d", activity_mainValue); //setContentView(R.layout.activity_main); jmethodID setContentViewID = env->GetMethodID(AppCompatActivityClazz, "setContentView", "(I)V"); env->CallVoidMethod(thiz, setContentViewID, activity_mainValue); //R.id.sample_text jclass R$idClazz = env->FindClass("com/example/demo/R$id"); jfieldID sample_textID = env->GetStaticFieldID(R$idClazz, "sample_text", "I"); int sample_textValue = env->GetStaticIntField(R$idClazz, sample_textID); LOGD("sample_textValue=%d", sample_textValue); //TextView tv = findViewById(R.id.sample_text); jmethodID findViewByIdID = env->GetMethodID(AppCompatActivityClazz, "findViewById", "(I)Landroid/view/View;"); jobject TextViewObj = env->CallObjectMethod(thiz, findViewByIdID, sample_textValue); //nativePathA = new Utils().getPath(getApplicationContext()) + "/libexampleA.so"; //nativePathB = new Utils().getPath(getApplicationContext()) + "/libexampleB.so"; jclass UtilsClazz = env->FindClass("com/example/demo/Utils"); jmethodID getPathID = env->GetMethodID(UtilsClazz, "getPath", "(Landroid/content/Context;)Ljava/lang/String;"); jmethodID UtilsInitID = env->GetMethodID(UtilsClazz, "<init>", "()V"); jobject UtilsObj = env->NewObject(UtilsClazz, UtilsInitID); jclass ContextWrapperClazz = env->FindClass("android/content/ContextWrapper"); jmethodID getApplicationContextID = env->GetMethodID(ContextWrapperClazz, "getApplicationContext", "()Landroid/content/Context;"); jobject ContextObj = env->CallObjectMethod(thiz, getApplicationContextID); jstring nativePath = static_cast<jstring>(env->CallObjectMethod(UtilsObj, getPathID, ContextObj)); std::string nativePathCStr = env->GetStringUTFChars(nativePath, nullptr); std::string nativePathACStrA = nativePathCStr + "/libexampleA.so"; std::string nativePathACStrB = nativePathCStr + "/libexampleB.so"; LOGD("ndk nativePathA=%s", nativePathACStrA.c_str()); LOGD("ndk nativePathB=%s", nativePathACStrB.c_str()); jclass MainActivityClazz = env->GetObjectClass(thiz); jfieldID nativePathBID = env->GetFieldID(MainActivityClazz, "nativePathB", "Ljava/lang/String;"); env->SetObjectField(thiz, nativePathBID, env->NewStringUTF(nativePathACStrB.c_str())); //stringFromJNIA(nativePathB) jmethodID stringFromJNIAID = env->GetMethodID(MainActivityClazz, "stringFromJNIA", "(Ljava/lang/String;)Ljava/lang/String;"); jstring stringFromJNIARetval = static_cast<jstring>(env->CallObjectMethod(thiz, stringFromJNIAID, env->NewStringUTF( nativePathACStrB.c_str()))); //tv.setText(stringFromJNIA(nativePathB)); jclass TextViewClazz = env->GetObjectClass(TextViewObj); jmethodID setTextID = env->GetMethodID(TextViewClazz, "setText", "(Ljava/lang/CharSequence;)V"); env->CallVoidMethod(TextViewObj, setTextID, stringFromJNIARetval); //stringFromJNIB(nativePathA) jmethodID stringFromJNIBID = env->GetMethodID(MainActivityClazz, "stringFromJNIB", "(Ljava/lang/String;)Ljava/lang/String;"); env->CallObjectMethod(thiz, stringFromJNIBID, env->NewStringUTF(nativePathACStrA.c_str())); } 複製代碼