android ndk返回String(字符串)

android ndk环境搭建就不详细介绍。

首先介绍NDK方法直接返回字符串

1、env->NewStringUTF(char* str)

2、先把char*或者char[]数组转化为字符串变量,代码如下:

jstring pcharToJstring(JNIEnv* env, const char* pat, const char* encoding)
{
    jclass    gStringClass;
    jmethodID gmidStringInit;
    jmethodID gmidStringGetBytes;
    gStringClass= (*env)->FindClass(env,"java/lang/String");
    gmidStringGetBytes= (*env)->GetMethodID(env,gStringClass, "getBytes", "(Ljava/lang/String;)[B");
    gmidStringInit= (*env)->GetMethodID(env,gStringClass, "<init>", "([BLjava/lang/String;)V");
    jstring jencoding;
    jbyteArray bytes = (*env)->NewByteArray(env,strlen(pat));
    (*env)->SetByteArrayRegion(env,bytes, 0, strlen(pat), (jbyte*)pat);
    if (encoding==NULL)
        jencoding= (*env)->NewStringUTF(env,"utf-8");
    else
        jencoding=(*env)->NewStringUTF(env,encoding);
    return (jstring)(*env)->NewObject(env,gStringClass, gmidStringInit, bytes, jencoding);
}
上述代码主要把一个char*字符串转化为java String对象。

上面是方法直接返回字符串,下面讲述NDK方法返回Hello(练习代码随变取名)类里面含有String类型

Hello.java类代码

public class Hello {


    private int age;
    private String  name;


    public Hello(int    age,    String  name){
        this.age    =   age;
        this.name   =   name;
    }


    @Override
    public String toString() {
        return "Hello{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

hello-jni.c代码

#include <string.h>
#include <jni.h>
#include <android/log.h>
#define   LOG_TAG    "LOG_TEST"
#define   LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define   LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)


jstring pcharToJstring(JNIEnv* env, const char* pat, const char* encoding)
{
    jclass    gStringClass;
    jmethodID gmidStringInit;
    jmethodID gmidStringGetBytes;
    gStringClass= (*env)->FindClass(env,"java/lang/String");
    gmidStringGetBytes= (*env)->GetMethodID(env,gStringClass, "getBytes", "(Ljava/lang/String;)[B");
    gmidStringInit= (*env)->GetMethodID(env,gStringClass, "<init>", "([BLjava/lang/String;)V");
    jstring jencoding;
    jbyteArray bytes = (*env)->NewByteArray(env,strlen(pat));
    (*env)->SetByteArrayRegion(env,bytes, 0, strlen(pat), (jbyte*)pat);
    if (encoding==NULL)
        jencoding= (*env)->NewStringUTF(env,"utf-8");
    else
        jencoding=(*env)->NewStringUTF(env,encoding);


    return (jstring)(*env)->NewObject(env,gStringClass, gmidStringInit, bytes, jencoding);
}

jobject
Java_com_example_carrry_androidtest_MainActivity_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
     char  temp[30]    =   {'m','y',' ','i','s',' ','j','k'};
     char* hellos    =   NULL;
     jclass pedestrainDeadReckoningClass = (*env)->FindClass(env,"com/example/carrry/androidtest/util/Hello");
             jmethodID pedestrainDeadReckoningClassInit = (*env)->GetMethodID(env,pedestrainDeadReckoningClass, "<init>", "(ILjava/lang/String;)V");
    jstring hello   = pcharToJstring(env,temp,hellos);
    int age =   20;
    return  (*env)->NewObject(env,pedestrainDeadReckoningClass,pedestrainDeadReckoningClassInit,age,hello);
}

c里面代码主要先把char*字符串转化为JAVA String对象,再返回


Activity代码

public  native Hello stringFromJNI();


    static {
        System.loadLibrary("hello-jni");
    }
Hello  str =   stringFromJNI();
                button.setText(str.toString());

需要注意的小细节:

1、Java类的全地址

jclass pedestrainDeadReckoningClass = (*env)->FindClass(env,"com/example/carrry/androidtest/util/Hello");

2、new出Java类型对象参数一定要正确

jmethodID pedestrainDeadReckoningClassInit = (*env)->GetMethodID(env,pedestrainDeadReckoningClass, "<init>", "(ILjava/lang/String;)V");

这类型和个数一定要和你调用Java类的结构体类型和个数一样


总结:

c返回一个Java类对象,首先取到Java类地址(包名+类名),再取Java类的结构体参数个数和类型,再使用(*env)->NewObject方法把JAVA对象new出来。一般好久不使用NDK容易把参数个数和类型这东西忘记。

你可能感兴趣的:(android,String,NDK,Java类对象)