build.gradle (:app)
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
cmake_minimum_required(VERSION 3.10.2)
project("jnidemo")
add_library(
native-lib
SHARED #动态库
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(native-lib
${log-lib})
2022-07-09 10:33:51.136 2558-2558/com.gordon.jnitest E/.gordon.jnites: No implementation found for java.lang.String com.gordon.jnitest.MainActivity.func2() (tried Java_com_gordon_jnitest_MainActivity_func2 and Java_com_gordon_jnitest_MainActivity_func2__)
2022-07-09 10:33:51.136 2558-2558/com.gordon.jnitest D/AndroidRuntime: Shutting down VM
--------- beginning of crash
2022-07-09 10:33:51.138 2558-2558/com.gordon.jnitest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gordon.jnitest, PID: 2558
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:402)
at android.view.View.performClick(View.java:7441)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
at android.view.View.performClickInternal(View.java:7418)
at android.view.View.access$3700(View.java:835)
at android.view.View$PerformClick.run(View.java:28676)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7842)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397)
at android.view.View.performClick(View.java:7441)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
at android.view.View.performClickInternal(View.java:7418)
at android.view.View.access$3700(View.java:835)
at android.view.View$PerformClick.run(View.java:28676)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7842)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.gordon.jnitest.MainActivity.func2() (tried Java_com_gordon_jnitest_MainActivity_func2 and Java_com_gordon_jnitest_MainActivity_func2__)
at com.gordon.jnitest.MainActivity.func2(Native Method)
at com.gordon.jnitest.MainActivity.func2(MainActivity.java:34)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397)
at android.view.View.performClick(View.java:7441)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
at android.view.View.performClickInternal(View.java:7418)
at android.view.View.access$3700(View.java:835)
at android.view.View$PerformClick.run(View.java:28676)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7842)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
1、对应方法有没有加 extern “C”
2、准备看
static {
System.loadLibrary(“native-lib”);
}
3、配置
externalNativeBuild {
cmake {
path “src/main/cpp/CMakeLists.txt”
version “3.10.2”
}
}
#define JNIEXPORT __attribute__ ((visibility ("default")))
typedef _jstring* jstring;
#define JNICALL
extern "C"
JNIEXPORT jstring JNICALL
Java_com_gordon_jnitest_MainActivity_func3(JNIEnv *env, jobject thiz) {
// TODO: implement func3()
}
env是每个jni函数第一个参数
jobject thiz 就是mainactivity
public static native String func2();
extern "C"
JNIEXPORT jstring JNICALL
Java_com_gordon_jnitest_MainActivity_func2(JNIEnv *env, jclass thiz) {
// TODO: implement func2()
std::string hello = "func2";
return env->NewStringUTF(hello.c_str());
}
第二个参数不再是jobject 而变成 jclass
struct _JNIEnv {
...
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_gordon_jnitest_MainActivity_func3(JNIEnv *env, jobject thiz) {
// TODO: implement func3()
jclass pJclass = env->GetObjectClass(thiz);//获取java对象 mainactivity
jfieldID idText = env->GetFieldID(pJclass, "text", "Ljava/lang/String;");
jstring text = env->NewStringUTF("native 修改");
env->SetObjectField(thiz, idText, text);
std::string hello = "func3";
return env->NewStringUTF(hello.c_str());
}
public void callBack(int code) {
Toast.makeText(this, "native层回调: " + code, Toast.LENGTH_SHORT).show();
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_gordon_jnitest_MainActivity_func4(JNIEnv *env, jobject thiz) {
// TODO: implement func4()
jclass pJclass = env->GetObjectClass(thiz);//获取java对象 mainactivity
jmethodID idCallBack = env->GetMethodID(pJclass, "callBack", "(I)V");
env->CallVoidMethod(thiz, idCallBack, 2);
std::string hello = "func4";
return env->NewStringUTF(hello.c_str());
}