简体   繁体   English

JNI / Android:用C ++调用Java中的非静态方法?

[英]JNI / Android : call to non static method in Java from C++?

I have got the following JNI method which currently calls a static Java method: 我有以下JNI方法,它当前调用静态Java方法:

void bindToMarketBillingServiceJNI(const char *  inappID)
    {
        JniMethodInfo t;

        if (JniHelper::getStaticMethodInfo(t
            , "com/mycompany/games/js/TestsDemo"
            , "bindToMarketBillingService"
            , "(Ljava/lang/String;)V"))
        {
            jstring stringArg1;

            if (! inappID)
            {
                stringArg1 = t.env->NewStringUTF("1");
            }
            else
            {
                stringArg1 = t.env->NewStringUTF(inappID);
            }

            t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1);

            t.env->DeleteLocalRef(stringArg1);
            t.env->DeleteLocalRef(t.classID);

        }
    }

Here is my Java method : 这是我的Java方法:

public static void bindToMarketBillingService(final String mSku)
    {

// Some code....

}

Everything works fine. 一切正常。

But now, I want to make my Java method NON STATIC. 但是现在,我想让我的Java方法成为NON STATIC。 I thought that I just had to change: 我以为我只需改变:

  • JniHelper::getStaticMethodInfo to JniHelper::getMethodInfo JniHelper :: getStaticMethodInfo到JniHelper :: getMethodInfo
  • t.env->CallStaticVoidMethod to t.env->CallVoidMethod t.env-> CallStaticVoidMethod to t.env-> CallVoidMethod
  • 'public static void bindToMarketBillingService(final String mSku)' to 'public void bindToMarketBillingService(final String mSku)' 'public static void bindToMarketBillingService(final String mSku)'to'public void bindToMarketBillingService(final String mSku)'

But it crashes... (crash log below) 但它崩溃了......(下面的崩溃日志)

Anybody knows how to solve this issue ? 有谁知道如何解决这个问题?

Thanks !! 谢谢 !!

08-20 11:54:11.009: A/libc(9379): Fatal signal 11 (SIGSEGV) at 0x0c1f4072 (code=1)
08-20 11:54:11.109: D/dalvikvm(31592): GC_CONCURRENT freed 735K, 12% free 9743K/10951K, paused 4ms+7ms
08-20 11:54:11.184: D/dalvikvm(1976): GC_CONCURRENT freed 1720K, 35% free 28243K/43399K, paused 5ms+13ms
08-20 11:54:11.194: I/ApplicationPolicy(1976): getActualApplicationStateEnabled() : true
08-20 11:54:11.219: D/PJ_MainApplication(9698): onApplicationCreate -> Now
08-20 11:54:11.334: D/dalvikvm(31592): GC_CONCURRENT freed 273K, 9% free 9981K/10951K, paused 3ms+3ms
08-20 11:54:11.409: D/PJ_CrashManager(9698): registerHandler -> Current handler class = com.android.internal.os.RuntimeInit$UncaughtHandler
08-20 11:54:11.469: I/DEBUG(9331): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
08-20 11:54:11.469: I/DEBUG(9331): Build fingerprint: 'samsung/GT-I9100/GT-I9100:4.0.3/IML74K/XWLPG:user/release-keys'
08-20 11:54:11.469: I/DEBUG(9331): pid: 9379, tid: 9403  >>> com.audioguidia.games.js <<<
08-20 11:54:11.469: I/DEBUG(9331): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0c1f4072
08-20 11:54:11.474: I/DEBUG(9331):  r0 00000000  r1 10000000  r2 fffffffc  r3 4cbb9ef0
08-20 11:54:11.474: I/DEBUG(9331):  r4 00273f98  r5 4c7f7fc4  r6 51134ad4  r7 415077f8
08-20 11:54:11.474: I/DEBUG(9331):  r8 00000001  r9 0c1f4071  10 4cbb9ee4  fp 51134a58
08-20 11:54:11.474: I/DEBUG(9331):  ip ffffffec  sp 51134a58  lr 4096864d  pc 40968aac  cpsr 00000030
08-20 11:54:11.474: I/DEBUG(9331):  d0  0000000000000000  d1  3f80000000000000
08-20 11:54:11.474: I/DEBUG(9331):  d2  0000000000000000  d3  0000000000000000
08-20 11:54:11.474: I/DEBUG(9331):  d4  0000000000000000  d5  3f80000000000000
etc....

Changing just the call on the env object is not sufficient. 仅更改env对象上的调用是不够的。

First your new instance method should be declared in the Java class like: public void myMethod(...) (ie no static keyword here). 首先,您的新实例方法应该在Java类中声明,如: public void myMethod(...) (即此处没有static关键字)。

Secondly you need a java object reference to call an instance method, not just the class. 其次,您需要一个java对象引用来调用实例方法,而不仅仅是类。 ie you would do something like (please note I am using C syntax): 即你会做类似的事情(请注意我使用的是C语法):

jmethodID midCallBack = (*env)->GetMethodID(env, thisClass, "myMethod", "()V");
if (NULL == midCallBack) return;

// Call back the method (which returns void), based on the Method ID
(*env)->CallVoidMethod(env, thisObj, midCallBack);

See section "5.3 Callback Instance Methods and Static Methods" at this link for more information 有关详细信息,请参阅此链接中的 “5.3回调实例方法和静态方法”部分

If you want to call non-static method, you have to create an object of that class and after that only call member method. 如果要调用非静态方法,则必须创建该类的对象,然后才调用成员方法。 Code looks like this 代码看起来像这样

jmethodID constructor = env->GetMethodID(cls, "<init>", "()V"); //this is for defaul c-tor
jobject object = env->NewObject(cls, constructor);
//getting your method id
env->CallVoidMethod(object, methodId/*,your parameters*/); 

I just made a static method in java that call not static method: 我刚刚在java中创建了一个静态方法,它调用非静态方法:

static public void startActivity() {
    try {
        Activity mother = QtNative.activity();
        Intent intent = new Intent(mother, MainActivity.class);
        mother.startActivity(intent);
    } catch (Exception e) {
        Log.e(msgTag, e.toString());
        e.printStackTrace();
    }
}

And I called from C++ like this: 我从C ++那里打来电话:

void FacebookAndroid::startAndroidFacebook() {
QAndroidJniObject::callStaticMethod<void>("org.qtproject.example.MainActivity",
                                          "startFacebookActivity",
                                          "()V");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM