Android NDK(二)

1、方法签名

签名规则:
https://www.cnblogs.com/mingfeng002/p/6595047.html

查看方法签名的命令:
cd app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes
javap -s com.hzy.ndk.HelloWorld

Android NDK(二)_第1张图片
方法签名

2、C调Java静态方法

在内HelloWorld.java添加如下代码

    public static void logMessage(String data){
        Log.d("HelloWorld-log",data);
    }

    public static void staticMothod(String data){
        logMessage(data);
    }

    public static native void callStaticMothod(int i);

此时编译时会报错,我们重新执行:
cd app\src\main\java
javah -d ../jin com.hzy.ndk.HelloWorld
生成新的com_hzy_ndk_HelloWorld.h文件

之后在HelloWorld.cpp内添加如下代码:

/*
 * Class:     com_hzy_ndk_HelloWorld
 * Method:    callStaticMothod
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_com_hzy_ndk_HelloWorld_callStaticMothod__I(JNIEnv *env, jclass jc, jint i) {

    //找到对应的类
    jclass cls_hello = env->FindClass("com/hzy/ndk/HelloWorld");
    if (cls_hello == NULL) {
        return;
    }

    //找到java层需要调用的方法
    jmethodID mtd_static_method = env->GetStaticMethodID(cls_hello, "staticMothod",
                                                         "(Ljava/lang/String;)V");
    if (mtd_static_method == NULL) {
        return;
    }

    //声明传递的String
    jstring data = env->NewStringUTF("call java static callStaticMothod1 from c++");
    if (data == NULL) {
        return;
    }

    //调用Java层方法
    env->CallStaticVoidMethod(cls_hello, mtd_static_method, data);
    //删除引用
    env->DeleteLocalRef(cls_hello);
    env->DeleteLocalRef(data);
}

在MainActivity内执行

HelloWorld.callStaticMothod(1);
image.png

3、C调Java实例方法
在内HelloWorld.java添加如下代码

    public void mothod(String data){
        logMessage(data);
    }

    public native void callInstanceMothod(int i);

此时编译时会报错,我们重新执行:
cd app\src\main\java
javah -d ../jin com.hzy.ndk.HelloWorld
生成新的com_hzy_ndk_HelloWorld.h文件

之后在HelloWorld.cpp内添加如下代码:

/*
 * Class:     com_hzy_ndk_HelloWorld
 * Method:    callInstanceMothod
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_hzy_ndk_HelloWorld_callInstanceMothod__I
        (JNIEnv *env, jobject jb, jint i) {
    //找到对应的类
    jclass cls_hello = env->FindClass("com/hzy/ndk/HelloWorld");
    if (cls_hello == NULL) {
        return;
    }
    //找到对应的方法
    jmethodID mtd_mothod = env->GetMethodID(cls_hello, "mothod", "(Ljava/lang/String;)V");
    if (mtd_mothod == NULL) {
        return;
    }
    //找到对应的构造方法
    jmethodID mtd_construct = env->GetMethodID(cls_hello, "", "()V");
    if (mtd_construct == NULL) {
        return;
    }
    //创建相应的对象
    jobject hello = env->NewObject(cls_hello, mtd_construct, NULL);
    if (hello == NULL) {
        return;
    }
    jstring message = env->NewStringUTF("call instance mothod1");

    //调用java层方法
    env->CallVoidMethod(hello, mtd_mothod, message);

    //删除引用
    env->DeleteLocalRef(message);
    env->DeleteLocalRef(hello);
    env->DeleteLocalRef(cls_hello);
}

在MainActivity内执行

new HelloWorld().callInstanceMothod(1);
image.png

4、C修改Java内成员变量和静态成员变量

在内HelloWorld.java添加如下代码

    private static String name="mlx";

    public static void staticMothod(String data){
        logMessage(data);
        logMessage(name);
    }

    public static native void callStaticMothod(long l,String s);

此时编译时会报错,我们重新执行:
cd app\src\main\java
javah -d ../jin com.hzy.ndk.HelloWorld
生成新的com_hzy_ndk_HelloWorld.h文件

之后在HelloWorld.cpp内添加如下代码:

/*
 * Class:     com_hzy_ndk_HelloWorld
 * Method:    callStaticMothod
 * Signature: (JLjava/lang/String;)V
 */
JNIEXPORT void JNICALL
Java_com_hzy_ndk_HelloWorld_callStaticMothod__JLjava_lang_String_2(JNIEnv *env, jclass jc, jlong l,
                                                                   jstring s) {
    //找到对应的类
    jclass cls_hello = env->FindClass("com/hzy/ndk/HelloWorld");
    if (cls_hello == NULL) {
        return;
    }
    //找到java层需要调用的方法
    jmethodID mtd_static_mothod = env->GetStaticMethodID(cls_hello, "staticMothod",
                                                         "(Ljava/lang/String;)V");
    if (mtd_static_mothod == NULL) {
        return;
    }

    jfieldID fld_name = env->GetStaticFieldID(cls_hello, "name", "Ljava/lang/String;");
    if (fld_name == NULL) {
        return;
    }
    jstring name = env->NewStringUTF("hzy");
    env->SetStaticObjectField(cls_hello, fld_name, name);

    jstring data = env->NewStringUTF("call java static callStaticMothod2 from c++");

    if (data == NULL) {
        return;
    }

    //调用Java层方法
    env->CallStaticVoidMethod(cls_hello, mtd_static_mothod, data);
    //删除引用
    env->DeleteLocalRef(cls_hello);
    env->DeleteLocalRef(data);
    env->DeleteLocalRef(name);

}

在MainActivity内执行

HelloWorld.callStaticMothod(2,"callStaticMothod-静态方法2");
Android NDK(二)_第2张图片
image.png

修改成员变量的方法同上,有兴趣可以查阅demo.

5、反编译Crash日志

adb logcat|ndk-stack -sym F:\SelfDemo\ndk\app\build\intermediates\cmake\debug\obj\arm64-v8a

6、异常处理:

env->ExceptionOccurred() / env->ExceptionCheck()

if(env->ExceptionCheck()){
    env->ExceptionDescribe();
    env->ExceptionClear();
    jclass cls_exception = env->FindClass("java/lang/Exception");
    env->ThrowNew(cls_exception,"call java static method ndk error");
    env->DeleteLocalRef(cls_exception);
    return;
}

deom地址:https://github.com/hnhzy/ndk

参考文章:
https://blog.csdn.net/amoscxy/article/details/78962505
https://www.imooc.com/video/16126

你可能感兴趣的:(Android NDK(二))