NDK实战教程(一) 在Android Studio运行第一个NDK程序

来源:互联网 发布:密码 知乎 编辑:程序博客网 时间:2024/05/17 01:06

1、新建一个Android工程,这一步就不多说了;

2、在AndroidStudio中配置NDK路径,方法是:

(1)先下载NDK并安装(这句基本是废话);

(2)点菜单栏的File->ProjectStructure…->在打开的窗口中左侧选中SDKLocation->在右侧Android NDK Location中填入NDK目录所在路径,如下图所示:

  


3、编译生成.class文件,方法是:

点菜单栏的Build->Make Project,如下图所示;

        这时,在工程的app/build/intermediates下就会生成classes文件夹,打开classes目录下的debug目录就会看到以你的包名命名的各级文件夹,最里边文件夹下有你的Java类对应的.class文件;


然后:

在AS中新建一个Project,然后再新建一个class为NdkJniUtils,在内部声明native方法(jni使用的定义,后面系列教程会细说)。

package io.github.yanbober.ndkapplication;public class NdkJniUtils {    public native String getCLanguageString();}

在工程主文件Activity中写入如下代码调运JNI的东西显示在UI上。

public class MainActivity extends ActionBarActivity {    private TextView mTextView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTextView = (TextView) this.findViewById(R.id.test);        NdkJniUtils jni = new NdkJniUtils();        mTextView.setText(jni.getCLanguageString());    }}

然后Mark project得到其中中间文件,我们关注的是.class文件。编译OK以后生成的class文件在AS工程的如下目录:

NDKApplication\app\build\intermediates\classes\debug

然后接下来的步骤就是根据生成的class文件,利用javah生成对应的 .h头文件。

点开AS的Terminal标签,默认进入到该项目的app文件夹下。我在windows平台下输入如下命令跳转到class中间文件生成路径:

xxxxx\app> cd build\intermediates\classes\debug

然后执行如下javah命令生成h文件。

xxxxx\debug> javah -jni io.github.yanbober.ndkapplication.NdkJniUtils

执行完之后你可以在文件夹NDKApplication\app\build\intermediates\classes\debug下看见生成的 .h头文件为:

io_github_yanbober_ndkapplication_NdkJniUtils.h
 

其内容为:

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

在工程的main目录下新建一个名字为jni的目录,然后将刚才的 .h文件剪切过来。在jni目录下新建一个c文件,随意取名,我的叫jnitest.c 。然后编辑代码如下(后面会解释啥意思,这里重在工具使用):

#include "io_github_yanbober_ndkapplication_NdkJniUtils.h"/* * Class:     io_github_yanbober_ndkapplication_NdkJniUtils * Method:    getCLanguageString * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_io_github_yanbober_ndkapplication_NdkJniUtils_getCLanguageString  (JNIEnv *env, jobject obj){     return (*env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");  }

接下来在工程的local.properties文件中添加NDK路径(上面下载好的那个NDK),类似其中的SDK路径一样,我的添加后如下:

sdk.dir=D\:\\AndroidStdioSDK\\sdk#add by 工匠若水ndk.dir=D\:\\AndroidStdioSDK\\android-ndk-r10d-64bit

接下来在app module目录下的build.gradle中设置库文件名(生成的so文件名)。找到gradle文件的defaultConfig这项,在里面添加如下内容:

defaultConfig {    ......    ndk{        moduleName "YanboberJniLibName"         //生成的so名字        abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。目前可有可无。    }}

现在生成的so库名字也有了,那就去代码的NdkJniUtils java文件添加静态初始化load代码,添加如下:

static {        System.loadLibrary("YanboberJniLibName");   //defaultConfig.ndk.moduleName    }

好了,到此AS下NDK JNI开发的代码编写和设置就OK了,接下来就是编译工程运行就可以了。

在gradle.properties文件中增加

android.useDeprecatedNdk=true

在这里需要特别注意一点的是:

头文件中函数声明参数列表中只有参数类型,没有参数名。一般我们在.c文件中实现该方法时,很多时候是直接拷贝该函数到.c文件中写函数体,但是却忽略了实现函数时给该函数的参数列表中的参数写个临时的参数名。只要实现时加上参数名就行了:



 

 
阅读全文
0 0
原创粉丝点击