JNI初探

作者: 大明白 | 来源:发表于2015-11-21 17:55 被阅读249次

    NDK产生背景

    Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言。但这并不等同于“第三方应用只能使用Java”。在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的。

    不过,Google也表示,使用原生SDK编程相比Dalvik虚拟机也有一些劣势,Android SDK文档里,找不到任何JNI方面的帮助。即使第三方应用开发者使用JNI完成了自己的C动态链接库(so)开发,但是so如何和应用程序一起打包成apk并发布?这里面也存在技术障碍。比如程序更加复杂,兼容性难以保障,无法访问Framework API,Debug难度更大等。开发者需要自行斟酌使用。

    于是NDK就应运而生了。NDK全称是Native Development Kit。

    NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。NDK将是Android平台支持C开发的开端。

    为什么使用NDK

    1. 代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
    2. 可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
    3. 提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
    4. 便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。

    配置环境

    1. 下载NDK,NDK下载路径
      Windows下的是一个自解压文件,下载完成后双击运行,文件会自解压到当前目录,记住该目录地址,配置AndroidStudio时需要使用到这个地址

    2. 打开AndroidStudio,File -> Project Structure打开对话框,在对话框中输入NDK路径(上面的解压路径)

    配置NDK路径.pic

    开启NDK之旅

    1.新建JNIDemo工程,打开MainActivity.java文件,在类内输入下面代码后,Build -> Make Project

    public native String getStringFromNative();
    

    2.在Terminal输入命令

    cd app\src\main
    javah -d jni -classpath C:\AndroidSdk\platforms\android-23\android.jar;..\..\build\intermediates\classes\debug com.sentu.jnidemo.MainActivity
    

    就会发现在main目录下多了一个jni文件夹,里面有生成好的头文件

    3.在jni目录下创建一个.c文件,实现头文件里声明的方法

    #include "com_sentu_jnidemo_MainActivity.h"
    
    JNIEXPORT jstring JNICALL Java_com_sentu_jnidemo_MainActivity_getStringFromNative(JNIEnv *env, jobject obj) {
        return (*env)->NewStringUTF(env, "I'm comes from to Native Function!");
    }
    

    4.在 local.properties 文件中设置ndk的路径

    ndk.dir=C\:\\AndroidSdk\\android-ndk-r10e
    

    5.在MainActivity.java文件中添加如下代码

    public class MainActivity extends Activity {
    
        public native String getStringFromNative();
    
        static {
            System.loadLibrary("MyJni");
        }
    
        TextView info;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            info = (TextView) findViewById(R.id.info);
            info.setText(getStringFromNative());
        }
    }
    

    6.运行,查看效果

    这个时候可能会出现一个问题

    Error:(13, 0) Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.

    解决方案: 在gradle.properties中添加android.useDeprecatedNdk=true

    相关文章

      网友评论

          本文标题:JNI初探

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