安卓系统开发之NDK

1、NDK开发之JNI编译与运行

1、表示Native 工程

build.gradle (:app)

externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }

2、CMakeLists.txt

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})

3、JNI方法没有加 extern “C” 报错

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”
}
}

4、JNIEXPORT 相当于java public

#define JNIEXPORT  __attribute__ ((visibility ("default")))
typedef _jstring*       jstring;
#define JNICALL

5、JNI方法

extern "C"
JNIEXPORT jstring JNICALL
Java_com_gordon_jnitest_MainActivity_func3(JNIEnv *env, jobject thiz) {
    // TODO: implement func3()
}

env是每个jni函数第一个参数
jobject thiz 就是mainactivity

6、静态方法

    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

7、JNIEnv 是个结构体

struct _JNIEnv {
...
}

8、访问java字符串,修改字符串

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());
}

安卓系统开发之NDK_第1张图片

9、native回调java


    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());
	}

10、cmake原理详解 androidstudio与cmake编译流程机制

你可能感兴趣的:(音视频开发之路,android,android,studio,java)