JNI和NDK

喜夏-厌秋 提交于 2020-02-05 05:23:17

JNI: Java Native Interface Java调用本地代码接口

NDK : Native development Kit 安卓提供的本地开发包,用于编译成.so文件 (linux平台的库文件)

ABI :Application binary interface 应用程序二进制接口 ,.os文件以lib开始,以abi结尾,以便各自Cpu调用对应的so文件

一、JNI流程

1、新建本地方法类,以native关键字标识,例如

public class JniTest {

    public native String getText();
    public native Void setText(String text);
}

2、使用javac生成class文件,然后使用javah生成.h文件(此处主要,由于.h文件中的函数名需要包名和方法名,所以javah的参数必须是完整的带包名的 例如 javah  com.test.jni.JniTest)

3、新建.c或者.cpp文件实现.h文件的函数

4、然后使用gcc 编译成so文件,需要linux环境。Android开发者可用NDK包中的ndk-build命令代替

二、NDK流程

1、新建本地方法类,以native关键字标识,例如

public class JniTest {

    public native String getText();
    public native Void setText(String text);
}

2、使用javac生成class文件,然后使用javah生成.h文件(此处主要,由于.h文件中的函数名需要包名和方法名,所以javah的参数必须是完整的带包名的 例如 javah  com.test.jni.JniTest)

3、在main文件夹下即和java文件夹同级新建jni文件夹,将.h文件放入其中,在该目录下新建.c和Android.mk和Application.mk文件

.c文件如下:

#include <jni.h>
#include <com_lihui_test_jni_JniTest.h>

JNIEXPORT jstring JNICALL
Java_com_lihui_test_jni_JniTest_getText(JNIEnv *env, jobject instance) {

    // TODO


    return (*env)->NewStringUTF(env, "hello jni");
}

JNIEXPORT jobject JNICALL
Java_com_lihui_test_jni_JniTest_setText(JNIEnv *env, jobject instance, jstring text_) {
    const char *text = (*env)->GetStringUTFChars(env, text_, 0);

    // TODO

    (*env)->ReleaseStringUTFChars(env, text_, text);
}

 Android.mk文件如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni //类库名称
LOCAL_SRC_FILES := jnitest.c //编译的文件
include $(BUILD_SHARED_LIBRARY) //shared可用如apk包

 Application下 

APP_ABI := all //全部类型

 4、使用ndk-build编译成so文件 主要需要配置环境变量 指定工程目录 例如  ndk-build NDK_PROJECT_PATH=D:\Android\WorkSpace\JNI\app\src\main 保证jni文件夹在此目录下,然后就会生成libs,obj等文件夹,包含了so文件

   5、在main下新建jniLibs文件夹,将libs下的so文件拷入

 6、然后修改本地方法类 调用本地方法类 如下

public class JniTest {
    static {
        System.loadLibrary("hello-jni");
    }
    public native String getText();
    public native Void setText(String text);
}



public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) findViewById(R.id.tv);
        JniTest jniTest = new JniTest();
        tv.setText(jniTest.getText());
    }
}

  

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!