【问题标题】:Why "java.lang.NoSuchMethodError: no static method" from (JNIenv*)->GetStaticMethodID?为什么来自 (JNIenv*)->GetStaticMethodID 的“java.lang.NoSuchMethodError:没有静态方法”?
【发布时间】:2019-04-10 09:24:13
【问题描述】:

我的 Android NDK 项目的 Java 代码调用 C++ 函数,

    extern "C" JNIEXPORT jstring JNICALL Java_com_crimson_tub_MainActivity_stringFromJNI(JNIEnv *env, jobject jo)

我想打电话

    public static void requestPermissions(@NonNull final Activity activity, @NonNull final String[] permissions, @IntRange(from = 0L) final int requestCode) 

在 Android 文档中找到:

https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity, java.lang.String[], int)

我已经尝试了一些我认为问题所在的代码变体,

jmethodID jmid = env->GetStaticMethodID(clzz,"requestPermissions", "(Landroid/app/Activity;[Ljava/lang/String;I)V;"),
//jmethodID jmid = env->GetStaticMethodID(clzz,"requestPermissions", "(Lcom/company/project/MainActivity;[Ljava/lang/String;I)V;"),
  //jmethodID jmid = env->GetStaticMethodID(clzz,"requestPermissions", "(Ljava/lang/Object;[Ljava/lang/String;I)V;"),

上述所有替代方案都会导致相同的异常,

    No pending exception expected: java.lang.NoSuchMethodError: no static method "Landroid/support/v4/app/ActivityCompat;.requestPermissions(Landroid/app/Activity;[Ljava/lang/String;I)V;"

c++代码,

    extern "C" JNIEXPORT jstring JNICALL
    Java_com_crimson_tub_MainActivity_stringFromJNI(JNIEnv *env,jobject jo) {

        std::string hello;

        jobjectArray ret;
        int i;

        char *data[2]= { "android.permission.CAMERA" ,
                 "android.permission-group.CALENDAR"};

        ret= (jobjectArray)env->NewObjectArray(2,env->FindClass("java/lang/String"),env->NewStringUTF(""));

        for(i=0;i<2;i++) env->SetObjectArrayElement(ret,i,env->NewStringUTF(data[i]));

        jint result = 0xffffffff;

        jclass clzz = env->FindClass("android/support/v4/app/ActivityCompat");
        if (!clzz){
            hello += "-class";
        }else{
            hello += "+class";
        }

        jmethodID jmid = env->GetStaticMethodID(clzz,"requestPermissions", "(Landroid/app/Activity;[Ljava/lang/String;I)V;"),
        //jmethodID jmid = env->GetStaticMethodID(clzz,"requestPermissions", "(Lcom/company/project/MainActivity;[Ljava/lang/String;I)V;"),
          //jmethodID jmid = env->GetStaticMethodID(clzz,"requestPermissions", "(Ljava/lang/Object;[Ljava/lang/String;I)V;"),

        env->CallStaticVoidMethod(clzz,jmid,jo,ret,result);

        env->DeleteGlobalRef(jo);
        return env->NewStringUTF(hello.c_str());

    }

我希望能够通过 JNI 调用 Android Java 函数,例如,

    ActivityCompat.requestPermissions 

直接来自 c++,所以以后我可以从我的项目中删除 Java 代码。

我已经在这个问题上工作了很长一段时间,但仍然没有成功。

感谢所有帮助,非常感谢。

谢谢大家。

【问题讨论】:

  • 从什么时候开始Activity 等同于方法签名中的java.lang.Object?你的方法签名是错误的。不要猜这个。从javap -s 获取。永远不会错。
  • @user207421 表示第一个注释行。它还返回 java.lang.NoSuchMethodError 与 (Landroid/app/Activity;[Ljava/lang/String;I)V;"
  • 发现:javap 在 android.jar 中找不到“android.support.v4.app.ActivityCompat”。我正在使用 SDK 28。我认为这是相关的,失败是在 FindClass()。但它返回不为空。有什么建议/想法吗?
  • 您应该在传递给FindClass 的名称中使用斜杠,而不是点。
  • 修复了它。但结果相同

标签: c++ android-ndk jnienv


【解决方案1】:

问题是 ;在签名中的 V 之后。现在它可以工作了。哈哈。

【讨论】:

    猜你喜欢
    • 2018-09-21
    • 2018-05-20
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 2018-04-10
    • 2018-08-02
    相关资源
    最近更新 更多