安卓开发现在确实已经进入了一个新的阶段。越来越重视运行的效率了。不然怎么会出来一个ART运行模式。所以NDK编程也可以进行很多绕开安卓机制的工作。现在主要做一下NDK编程的配置工作。
1Android Studio
这个是google推荐的用于安卓开发的工具。还是不错。用AS最大的好处是,比Eclipse省去了自己写makefile的步骤
2NDK
NDK是个大文件需要自己单独下载
我使用的NDK是android-ndk-r10b
做NDK这些东西来说。最好还是把AS,NDK都用最新的。不然会出来很多问题的。
下面是配置步骤
1告诉AS你的NDK在哪里
(as,NDK的目录都不要用空格或者汉字)
File ->ProjectStructure
2生成java
熟悉jni编程的来说这个和标准的java生成没啥不一样的地方
NDK的文件内容如下
package com.example.bleuesprit.myapplication;
public class NDK {
static {
System.loadLibrary("Jni");//导入生成的链接库文件
}
public native String getStringFromNative();//本地方法
}
这里面getStringFromNative这个就是我们声明的jni函数等会要用c++实现。而System.loadLibrary(“Jni”)这个是为了装在我们生成的so文件的。我们c++编译过后的代码就放在so文件里面给java调用。至于为啥里面写的是Jni。这个是我们自己定义的。对应的文件是libJni.so这个文件。等下我们会看到怎么定义。
3生成头文件
在生成头文件的时候。我感觉AS里面有更加方便的方法。如果以后知道会回来修改。目前使用的标准的java方法就是先编译出来class再用javah生成c++的头文件。
首先我们要reBuild一下项目。目的是让AS重新编译我们所有的java文件产生相应的class类。
然后再AS的命令行里面用javah生成头文件
<项目名>\app\build\intermediates\classes\debug我们要在进入这个文件夹
因为我们的NDKjava文件的包是com.example.bleuesprit.myapplication
所以我们要执行的命令是
javah -jni com.example.bleuesprit.myapplication.NDK
至于javah的用法。大家自行百度。
命令执行之后会在debug这个目录下面生成一个c的头文件
编写c代码
首先新建一个jni目录。这个目录名字不是随便起的位置也不能随便放
这个目录要和java源码的目录是平级的。
把之前的头文件剪切的这个目录下面。然后新建一个c++文件去实现这里的代码。
我新建的文件叫newCppClass.cpp大家不要见怪。
然后里面的文件内容是
//
// Created by bleuesprit on 2016/3/23.
//
#include "com_example_bleuesprit_myapplication_NDK.h"
JNIEXPORT jstring JNICALL Java_com_example_bleuesprit_myapplication_NDK_getStringFromNative
(JNIEnv *env, jobject obj) {
return env->NewStringUTF("这里是来自c的string");
}
我们在这里面实现了java定义的native函数。
ndk的编程方式和jni的编程方式是一样的。并没有特别之处。
配置项目属性
虽然我们实现的c++。但是项目还不能编译他。因为我们的项目还没有进行配置
我们要配置几个地方。
这行的意思是不管NDK是不是过期了。我们还是要用。其实即使AS。NDK都是最新的还是会报这个错误。
第二个要配置的地方就是我们要配置需要生成so的文件的名字。还要配置一下源码目录
红框框里面就是我们加入的东西。ndk段代码要放在defaultconfig里面。sourceSets和defaultconfig平级
这里面写的Jni就是我们生成so的名字。所以在NDK.java文件里面静态加载的名字就是在这里面定义的。
使用jni
我们在里面调用一下c++函数
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
TextView textView=(TextView)findViewById(R.id.testText);
NDK ndk=new NDK();
textView.setText(ndk.getStringFromNative());
}
运行
按道理来说目前来说就可以正常运行了。不过不过。AS里面有个BUG。我遇到了一个报错
ndk-build.com finished with non-zero exit value 2
在编译的时候有这个错误。*里面说的是这个BUG的解决方法就是新建一个啥都不干的c++文件就能解决。果然,真的就能解决。
运行效果如下