zoukankan      html  css  js  c++  java
  • Android jni 编程1(对基本类型字符串的操作)

    最近一直在学安卓的jni,主要参考的是黑马程序员的视频教程,讲的确实不错。

    那就自己总结一下吧,算是对学习的复习。

    这篇博客也主要参考了这位博主:http://www.cnblogs.com/activity-life/p/3643047.html,在这里谢谢了

    通过他的博客和视频教程,我结合了两者的方法,把功能实现了,毕竟这个是应用为主,自己学艺不精,这里积累下:

    第一篇博客的总结所有Java调取jni是关于字符串的操作,主要包括以下三种类型:

    //对基本数据类型字符串的访问
       //0.无输入,有输出为字符串
       public native String helloFromC();
    
       //1.有输入,有输出访问字串
       private native String GetNativeString(String str);
    
      //2.输入字符串,并附带长度,输出字符串
      public native String encode(String text,int length);
      public native String decode(String text,int length);

    那么根据教程所讲,当有输入字符串作为参数传过来时,使用如下函数将其转换为C语言的字符串函数指针:

    //把java的字符串转换成c的字符串
    char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
    {
         char*   rtn   =   NULL;
         jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String");
         jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");
         jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B");
         jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
         jsize   alen   =   (*env)->GetArrayLength(env,barr);
         jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
         if(alen   >   0)
         {
          rtn   =   (char*)malloc(alen+1);         //""
          memcpy(rtn,ba,alen);
          rtn[alen]=0;
         }
         (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //
         return rtn;
    }

    之后对其操作,这里我将对以上三种类型分别展示jni中的使用:

    0.无输入,有输出为字符串:
    jstring Java_com_swust_string_MainActivity_helloFromC(JNIEnv* env,jobject obj){
       //C语言的字符串
        char* cstr="hello paopao from C";
       //把C语言字符串转换为Java的字符串
        //jstring     (*NewStringUTF)(JNIEnv*, const char*);
        //jstring jstr=(*(*env)).NewStringUTF(env,cstr)
        jstring jstr = (*env)->NewStringUTF(env, cstr);
    
        return jstr;
    }
    1.有输入,有输出访问字串:
    //把java的字符串转换成c的字符串
    char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
    {
         char*   rtn   =   NULL;
         jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String");
         jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");
         jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B");
         jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
         jsize   alen   =   (*env)->GetArrayLength(env,barr);
         jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
         if(alen   >   0)
         {
          rtn   =   (char*)malloc(alen+1);         //""
          memcpy(rtn,ba,alen);
          rtn[alen]=0;
         }
         (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //
         return rtn;
    }
    JNIEXPORT jstring JNICALL Java_com_swust_string_MainActivity_GetNativeString
      (JNIEnv *env, jobject obj, jstring jstr){
        //获取输入的字符串
        char* cstr=Jstring2CStr(env,jstr);
        char* pUTF8Str = "From jni String";
        strcat(cstr, "/");    //加一个分隔符
        strcat(cstr, pUTF8Str);    //联接一个本地字串
        //C语言的字符串转换为jstring
        return (*env)->NewStringUTF(env,cstr);
    }

    自己实现的基本功能是将Java传入的字符串和C的字符串合并,并返回。

    2.输入字符串,并附带长度,输出字符串:
    该种类型根据教程写了两个函数(编码和解码),可视为同一种类型:
    //把java的字符串转换成c的字符串
    char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
    {
         char*   rtn   =   NULL;
         jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String");
         jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");
         jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B");
         jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
         jsize   alen   =   (*env)->GetArrayLength(env,barr);
         jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
         if(alen   >   0)
         {
          rtn   =   (char*)malloc(alen+1);         //""
          memcpy(rtn,ba,alen);
          rtn[alen]=0;
         }
         (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //
         return rtn;
    }
    JNIEXPORT jstring JNICALL Java_com_swust_string_MainActivity_GetNativeString
      (JNIEnv *env, jobject obj, jstring jstr){
        //获取输入的字符串
        char* cstr=Jstring2CStr(env,jstr);
        char* pUTF8Str = "From jni String";
        strcat(cstr, "/");    //加一个分隔符
        strcat(cstr, pUTF8Str);    //联接一个本地字串
        //C语言的字符串转换为jstring
        return (*env)->NewStringUTF(env,cstr);
    }
    JNIEXPORT jstring JNICALL Java_com_swust_string_MainActivity_encode
      (JNIEnv *env, jobject obj, jstring jstr , jint length){
      //根据老师给的函数,生成C语言的字符指针
      //arg1:Java环境指针  arg2:java的字符串
        char* cstr=Jstring2CStr(env,jstr);
        int i=0;
        //C语言的int和jint的相同,故直接使用length
        for(i=0;i<length;i++){
            *(cstr+i)+=1;
        }
        //C语言的字符串转换为jstring
        return (*env)->NewStringUTF(env,cstr);
    }

    为了代码看起来比较明了,这里不贴项目代码了,只展示效果图:

    0.无输入,有输出为字符串:显示“hello paopao from c"
    1.有输入,有输出访问字串:显示”hello from java / hello from jni"
    2.输入字符串,并附带长度,输出字符串:显示编码和解码功能:

    
    
  • 相关阅读:
    最大团问题
    树的重心与相关性质
    2020年牛客算法入门课练习赛3 B
    牛客练习赛66 E
    浅谈后缀数组SA
    [随机化算法] 听天由命?浅谈Simulate Anneal模拟退火算法
    “优美的暴力”——树上启发式合并
    [线段树系列] LCT打延迟标记的正确姿势
    [Tarjan系列] Tarjan算法与有向图的SCC
    [Tarjan系列] 无向图e-DCC和v-DCC的缩点
  • 原文地址:https://www.cnblogs.com/shuqingstudy/p/4907936.html
Copyright © 2011-2022 走看看