Android Studio下的NDK开发

来源:互联网 发布:北师大网络不好 编辑:程序博客网 时间:2024/05/23 00:00

一.添加native方法

创建一个类,例如起名HelloJni,然后创建native方法。

public class HelloJni {    public native String append(String str1, String str2);    public native String sayHello();}

二.生成头文件

1.生成class文件,

build一下工程 (Build - Rebuild Project),会在app/intermediates/classes/debug/ 目录下会生成所有类的class文件。

2.生成头文件

在Android Studio上找到Terminal,然后通过命令切换到app/intermediates/classes/debug/ 目录下

通过 javah -jni 命令生成头文件,我们要生成的是com\njj\ndktest1目录下的HelloJni.class对应的有文件。

执行命令为 javah -jni com.njj.ndktese1.HelloJni


然后会在debug目录下多出一个.h文件。


然后再src/main/目录下创建jni目录,将com_njj_ndktese1_HelloJni.h文件复制进去

三.实现头文件中声明的函数

在jni目录下,创建一个.c文件,例如叫做 HelloJni.c

编写HelloJni.c文件,内容如下:

#include <jni.h>#include <malloc.h>#include <string.h>JNIEXPORT jstring JNICALL Java_com_njj_ndktest1_HelloJni_append        (JNIEnv *env, jobject obj, jstring jstr1, jstring jstr2) {    const char *str1, *str2;    char *result;    int len1, len2;    jstring jresult;    str1 = (*env)->GetStringUTFChars(env, jstr1, NULL);    str2 = (*env)->GetStringUTFChars(env, jstr2, NULL);    len1 = strlen(str1);    len2 = strlen(str2);    result = malloc((len1 + len2) * sizeof(char));    strcpy(result, str1);    strcpy(result + len1, str2);    (*env)->ReleaseStringUTFChars(env, jstr1, str1);    (*env)->ReleaseStringUTFChars(env, jstr2, str2);    jresult = (*env)->NewStringUTF(env, result);    free(result);    return jresult;}JNIEXPORT jstring JNICALL Java_com_njj_ndktest1_HelloJni_sayHello(JNIEnv *env, jobject obj){    return (*env)->NewStringUTF(env, "Hello Jni");}
然后再jni目录下创建Android.mk和Application.mk文件

Android.mk文件内容如下

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := HelloJni1LOCAL_SRC_FILES :=HelloJni.cinclude $(BUILD_SHARED_LIBRARY)
LOCAL_MODULE这是你最终生成的so文件的名字,最终格式为libHelloJni.so,每一个so文件的格式都是lib***.so,

LOCAL_SRC_FILES是你需要编译的c文件。

Application.mk文件内容如下

APP_ABI := armeabi armeabi-v7a
指定编译的ABI架构为armeabi和armeabi-v7a。如果需要别的,还可以添加,空格隔开,如果是所有的,直接写

APP_ABI := all
最终jni目录下的结构如下图:



四.生成so文件

在Terminal下,切换到目录app/src/main/jni下,亲测app/sec/main/下也可以,还有,这个目录的名字必须起名为jni,如果起名别的目录,ndk编译会找不到,

ndk编译会默认寻找jni/Android.mk文件,如果起了别的名字,还需要指定一些参数。比如,我把jni目录改成了jnis,执行命令就应该指定APP_BUILD_SCRIPT,

也就是Android.mk的路径,执行命令为: ndk-build APP_BUILD_SCRIPT=jnis/Android.mk.

执行ndk-build命令(需要安装ndk-build以及配置环境变量,百度搜Android Studio安装NDK这类的文章)


内容如下,说明执行成功。查看src/main目录下会生成libs和obj目录,libs目录下就是对应的so文件


libs是需要的内容,obj目录下,可以删除。

五.调用native方法

1.配置build.gradle文件

在app的build.gradle文件的android节点下,添加如下内容

    sourceSets {        main {            jniLibs.srcDirs = ['src/main/libs'] // 指定加载so的路径,如果不添加,将提示找不到library            jni.srcDirs = [] //        }    }
至少目前测试,这两行,少一行都会运行不起来。

2.加载so文件

在HelloJni.java文件中,加载so文件,


写在别的地方也可以,但是需要保证,在调用方法之前,必须加载了so文件。

3.调用方法

然后在需要的地方直接调用方法即可

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        HelloJni helloJni = new HelloJni();        Toast.makeText(MainActivity.this, helloJni.append("fds", "65dsss") + "\t\n" + helloJni.sayHello(), Toast.LENGTH_SHORT).show();    }}
运气之后,就会看到效果。



参考链接:

Android Studio下的JNI开发(一):NDK配置

Android Studio下的JNI开发(二):C/C++代码编写与编译

Android Studio NDK开发 -Hello World

Android Studio NDK开发与调试(生成.so文件)

Android 程序编译原理之浅析 

Android NDK开发起步Hello Jni

Android.mk文件语法详解





原创粉丝点击