zoukankan      html  css  js  c++  java
  • 编程基础知识——Java JNI开发流程(2)

    android中使用jni调用本地C++库 

    android平台上的本地库文件后缀 .so。类似windows上的dll文件。


    要在android上使用jni。首先须要下载android ndk。


    操作步骤,正常建立androidproject,然后在androidproject那里右键。属性,选择Android Tools -> Add Native Support。就能够为androidproject添加本地库支持。

    加入支持后的androidproject,会添加jni文件夹,C++代码就写在这个文件夹里。


    新建一个类。而且使用native修饰一个函数。这个函数就是须要本地库来实现的。本样例中的本地库函数作用是将字符串进行内置算法转换,server可依据这个转换识别client的合法性,使用jni的目的是添加代码反编译破解的复杂度。


    package com.show.shownative.lib;
    
    public class ShowNativeLib {
    	public native String showConvertCode(String param);	
    }
    

    使用javah生成头文件:ShowNativeLib.h

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_show_shownative_lib_ShowNativeLib */
    
    #ifndef _Included_com_show_shownative_lib_ShowNativeLib
    #define _Included_com_show_shownative_lib_ShowNativeLib
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_show_shownative_lib_ShowNativeLib
     * Method:    showConvertCode
     * Signature: (Ljava/lang/String;)Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_show_shownative_lib_ShowNativeLib_showConvertCode
      (JNIEnv *, jobject, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    在android的nativeproject设置中须要 mk文件类进行编译配置。

    本样例中须要用到三个MK ,系统会为你自己主动创建一个,照着路径新建两个就能够了

    1、Application.mk 内容例如以下

    APP_STL := stlport_static
    APP_ABI := armeabi armeabi-v7a mips x86
    

    以上两行配置说明:第一个是添加C++ STL模版支持。第二个是设置须要为哪几种CPU架构编译so文件。


    2、Android.mk 内容例如以下

    LOCAL_PATH := $(call my-dir)
    
    include $(LOCAL_PATH)/ShowNativeLib.mk
    

    以上的配置,第一行是死的。

    第二行是一个多模块引入方式。假设你还有其它本地库模块,能够分模块。这里include即可了。


    3、ShowNativeLib.mk 内容例如以下

    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := ShowNativeLib
    LOCAL_SRC_FILES := ShowMD5.cpp ShowNativeLib.cpp
    
    include $(BUILD_SHARED_LIBRARY)

    这个文件才是我们样例里面測试的这个模块的配置。

    ShowNativeLib.cpp 就是我们的实现文件,ShowMD5.cpp是一个第三方MD5摘要算法开源库。(这里得吐槽一下,MD5。SHA1这样的都叫摘要算法(DIGEST)。由于发现非常多人都没搞懂而喊它加密算法。




    当中ShowNativeLib.cpp的代码实现例如以下:解释都在代码里。


    #include <jni.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <ShowMD5.h>
    #include <ShowNativeLib.h>
    
    #define CONVERT_KEY ("sobey_showfun_convert_key_47511441331441")
    
    JNIEXPORT jstring JNICALL Java_com_show_shownative_lib_ShowNativeLib_showConvertCode(JNIEnv* pEnv, jobject obj, jstring param)
    {
    	if(!param)
    		return NULL ;
    
    	/*
    	 *  JNI里面操作java对象的方式,全都是基于java反射机制来做的。
    	 *  假设你全然没接触过java反射。那么你先应该去查查java反射的资料。
    	 *  以下仅仅做基本解释。不做深入讨论。 
    	 */
    	
    	//取得java.lang.String的class
    	jclass  clzString 	   = pEnv->FindClass("java/lang/String");
    	//取得String.getBytes的函数的Method对象
    	jmethodID getMethod    = pEnv->GetMethodID(clzString,"getBytes","()[B");
    	//运行这个Method。得到String.getBytes返回的字节数组。
    	jobject byteObj        = pEnv->CallObjectMethod(param, getMethod);
    	jbyteArray paramBytes  = (jbyteArray)byteObj ;
    	//将java的byte[]转成C++的 unsigned char*。

    以进行后面的转换算法。

    unsigned char* pBufIn = (unsigned char*)pEnv->GetByteArrayElements(paramBytes,NULL); jsize paramByteLen = pEnv->GetArrayLength(paramBytes); //调用MD5库,进行摘要处理。 std::string paramMd5 = GetMD5Code(pBufIn, (int)paramByteLen); int lengthMd5 = paramMd5.size(); //将内置的转换key,进行MD5处理 std::string paramKey = GetMD5Code((unsigned char*)CONVERT_KEY,strlen(CONVERT_KEY)); //进行转换算法。 for(int idx=0; idx<lengthMd5; idx++) { paramMd5[idx] ^= paramKey[idx]; paramMd5[idx] |= 0x31 ; } //将结果MD5二进制数据,转化成16进制表示的字符串 std::string resultMD5 = GetMD5Code((unsigned char*)paramMd5.c_str(),paramMd5.size()); //将C++字符串转化成java字符串。

    jstring result = pEnv->NewStringUTF(resultMD5.c_str()); return result ; }


    以上就是android里面使用JNI的样例。

    jni还是非常有帮助的,android的java毕竟在效率上有瓶颈(解释性语言的虚拟机,多了一个解释层),非常多须要高效率的数据处理。还是免不了要调用本地库来处理。

    苹果ios和android机比起来。从技术角度来看,人家的objc语言和ios平台。就比android平台的java运行效率高,这是不争的事实。

    所以相同的硬件配置,苹果机跑起来的流畅度是android机比不了的。但让实际情况是android机的硬件配置高得令人抓狂。

  • 相关阅读:
    CodeForces 1294B Collecting Packages(排序+贪心)
    计算系数(组合数)
    垒骰子(矩阵快速幂)
    蒜头君倒水(矩阵快速幂)
    Buy Tickets POJ
    Billboard HDU
    树状数组求逆序对 附HDU1394
    codeforces 1304D Shortest and Longest LIS
    codeforces 1301C Ayoub's function
    Codeforces 1301B Motarack's Birthday(二分)
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6893509.html
Copyright © 2011-2022 走看看