从Android中的JNI层调用jar文件方法

时间:2015-11-20 12:06:51

标签: android jar android-ndk java-native-interface

我正在尝试在android中创建一个带有JNI接口的应用程序。

下面是jar文件类:

package testjar;

public class JNICallInterface {
    public native String mymethod();
    public JNICallInterface() {
        // TODO Auto-generated constructor stub
    }

    public String getString(String sd) {
        return "Hello All, I am from JAR";
    }
    public void gotoJNI() {
        System.out.print(mymethod());
    }
}

下面是我的JNI文件:

#include <jni.h>

JNIEXPORT jint JNICALL Java_com_testndk_HelloWorld_messageFromNativeCode(
        JNIEnv * env, jobject jObj) {
    return 10;

}
JNIEXPORT jstring JNICALL Java_com_testndk_HelloWorld_textMessageFromNativeCode(
        JNIEnv * env, jobject jObj) {
    jclass clazz = (*env)->FindClass(env, "com/testndk/HelloWorld");
    jmethodID messageMe = (*env)->GetMethodID(env, clazz, "messageMe",
            "(Ljava/lang/String;)V");
    jstring jstr = (*env)->NewStringUTF(env, "This string comes from JNI");
    (*env)->CallVoidMethod(env, jObj, messageMe, jstr);
    return (*env)->NewStringUTF(env,
            "Hello all... I am from JNI method call");

}
JNIEXPORT jstring JNICALL Java_testjar_JNICallInterface_mymethod(JNIEnv * env,
        jobject jObj) {
    jclass clazz1 = (*env)->FindClass(env, "testjar/JNICallInterface");
    jmethodID messageMe1 = (*env)->GetMethodID(env, clazz1, "getString", "(Ljava/lang/String;)V");
    jstring string = (*env)->CallObjectMethod(env, jObj, messageMe1,"ada");
    return (*env)->NewStringUTF(env,string);
}

以下是LauncherActivity:

package com.testndk;

import testjar.JNICallInterface;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class HelloWorld extends Activity {
    TextView txtHello;

    static {
        System.loadLibrary("HelloWorld");// (“HelloWorld”);
    }

    public native int messageFromNativeCode();

    public native String textMessageFromNativeCode();
    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        txtHello = (TextView) findViewById(R.id.txtHello);
        //int i = messageFromNativeCode();
        String str = textMessageFromNativeCode();
        txtHello.setText(str);
        JNICallInterface in=new JNICallInterface();
        in.gotoJNI();
    }
    public void messageMe(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
}

当我尝试从JNI层调用jar方法时,我得到一个“NoSuchMethod”异常。

是否真的可以从JNI层调用Jar文件方法。我在这里错过了什么吗?

请帮忙!

P.S:我是JNI的新手

1 个答案:

答案 0 :(得分:0)

感谢fadden和Zaboj :)我能够调用该方法并使用正确的签名打印语句。

我的jar方法::

public String getString() {
        return "Hello All, I am from JAR";
    }

我的JNI电话::

JNIEXPORT jstring JNICALL Java_testjar_JNICallInterface_mymethod(JNIEnv * env,
        jobject jObj) {
    __android_log_print(2, APPNAME, "inside my method");
    jclass clazz1 = (*env)->FindClass(env, "testjar/JNICallInterface");
    __android_log_print(2, APPNAME, "class init");
    jmethodID messageMe1 = (*env)->GetMethodID(env, clazz1, "getString", "()Ljava/lang/String;");
    __android_log_print(2, APPNAME, "found my method");
    jstring string =(jstring)(*env)->CallObjectMethod(env,jObj, messageMe1);
    __android_log_print(2, APPNAME, "called method");
    const char *name = (*env)->GetStringUTFChars(env,string,JNI_FALSE);
    __android_log_print(2, APPNAME, "got string from jar :: %s",name);
    return string;
}

这完全没问题。包含用于交叉检查的日志语句。