美文网首页
Android studio JNI开发

Android studio JNI开发

作者: Nergal1 | 来源:发表于2017-06-16 11:44 被阅读0次

    这里的JNI开发是旧方法,在这里仅做记录使用,
    最新官方版已经默认使用cmake来编译:http://www.jianshu.com/p/2f3e0f589520

    说明:图片仅做效果展示,并不是JNI工程截图。
    1、编译环境的搭建
    正所谓:“工欲善其事必先利其器”嘛,所以先把改准备工具准备一下,因为是在studio下编译的,所以啊,什么studio、什么sdk、什么jdk,这些都自己去弄吧,这里说一下ndk这个编译C文件工具怎么下载安装;
    下载链接:https://developer.android.com/ndk/downloads/index.html(需要翻墙)进去之后下载自己相对应的ndk平台版本;
    下载完了之后直接是一个zip的压缩包,解压即可;
    然后如下图所示的配置ndk:
    ![](https://img.haomeiwen.com/i2687636/e99f6c92d7f46bea.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    然后你会在local.properties文件中看到:
    ![](https://img.haomeiwen.com/i2687636/5310f34175d5fd71.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    不要急,还没有完,ndk环境搭建还有最后一步,在gradle.properties的文件末尾加上android.useDeprecatedNdk=true这段代码,文字看不懂吧直接上图:
    ![](https://img.haomeiwen.com/i2687636/0c80b9dacd6e2f82.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    好了,到此处环境就搭建完毕了。
    2、java代码和C代码的编写步骤及过程
    首先新建一个java类JNIUtils.java

    public class JNIUtils {
     static
       {      
       System.loadLibrary("huazict");
       } 
    //java调C中的方法都需要用native声明且方法名必须和c的方法名一样
    public native String getString();
    }
    

    然后如下图所示重新Make Project一下工程:![](https://img.haomeiwen.com/i2687636/f728ba66ae540f73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    会在工程目录E:\work\MyApplication\stujni\build\intermediates\classes\debug\com\huazi\stujni\jni中看到自己编译后的class文件JNIUtils.class如下图所示:
    ![](https://img.haomeiwen.com/i2687636/25483a83c5d9e6ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    其次就是生成.h文件了
    在studio打开Terminal命令行工具,打开步骤是View->Tool Windows->Terminal (或直接按Alt+F12)

    然后在命令行中先进入到工程的classes目录下

     cd  /..../app/build/intermediates/classes/debug
    

    javah -jni 包路径+文件名:

      javah -jni com.huazi.stujni.jni.JNIUtils
    

    或者输入命令:javah -d jni -classpath 自己编译后的class文件的绝对路径:

    javah -d jni -classpath E:\work\MyApplication\stujni\build\intermediates\classes\debug com.huazi.stujni.jni.JNIUtils(注意debug后的空格)
    

    命令行中目录下会生成.h头文件,新建JNI文件夹如下图:


    Paste_Image.png

    这个文件.h文件不需要做任何修改,默认即可。
    现在我们来写一个test的C文件huazict.c同.h文件一样放到jni文件夹下,代码如下:

    #include "com_huazi_stujni_jni_JNIUtils.h"
    
    /**
    
     
    * 上边的引用标签一定是.h的文件名家后缀,方法名一定要和.h文件中的方法名称一样
    
     
    */
    
    JNIEXPORT jstring JNICALL Java_com_huazi_stujni_jni_JNIUtils_getString
    
            
    (JNIEnv *env, jobject obj) {
    
        
    return
    (*env)->NewStringUTF(env,
    "这是我测试的jni"
    );
    
    }
    

    如图所示:![](https://img.haomeiwen.com/i2687636/782d4cf6e0ccc298.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    最后在构建文件中的默认配置中加上:

    
    //ndk编译生成.so文件  
    ndk {
               moduleName "JpgLib"
               abiFilters "armeabi", "x86", "armeabi-v7a"//"arm64-v8a","x86_64"
               ldLibs "log"
           }
    

    如图:
    ![](https://img.haomeiwen.com/i2687636/219478d4e8c1903e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    到这里,通过jni调C就完成了

    三、调用编译过的.so库
    上边编译完成了,有人会问:我要的是编译后的.so库,别人用的时候直接拿来用就可以了,那编译后的.so库在哪呢?不要着急请看下图:
    ![](https://img.haomeiwen.com/i2687636/6a6678165371cbcf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    根据这个路径就可以找到指定输出的三种体系结构下的.so库文件,然后把.so文件复制出来,如下图所示的放到相应的文件夹下就ok了:
    ![](https://img.haomeiwen.com/i2687636/4370205734b7f0ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    再次运行,结果还是一样的,跟上边贴的那张图的显示效果是是一样的,同样能调用到,代码我就不上传了,都在上边贴上去了,而且也上传不了,公司的所有文件都是加密的,想上传都上传不了。
    到这里,整个jni的调用过程就结束了,包括调用jni需要的环境以及调用的过程,最后.so文件的导出,都在上边了,如果上边的jni调用过程有什么问题,欢迎留言,谢谢。

    相关文章

      网友评论

          本文标题:Android studio JNI开发

          本文链接:https://www.haomeiwen.com/subject/xiipqxtx.html