Android NDK开发-静态注册JNI Demo(二)

2018-08-05  本文已影响0人  家有萌犬

上文我们已经介绍了如何配置android studio环境来开发NDK,本篇实战开发,写一个简单的Demo。

public class MainActivity extends AppCompatActivity {

    // 用于在应用程序启动时加载“native-lib”库。
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }
    //使用C/C++实现
    public native String stringFromJNI();
}

使用上篇介绍的javah -jni命令工具可以生成头com_example_lynnlee_ndkdemo_MainActivity.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_lynnlee_ndkdemo_MainActivity */

#ifndef _Included_com_example_lynnlee_ndkdemo_MainActivity
#define _Included_com_example_lynnlee_ndkdemo_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_lynnlee_ndkdemo_MainActivity
 * Method:    stringFromJNI
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_lynnlee_ndkdemo_MainActivity_stringFromJNI
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

函数名Java_com_example_lynnlee_ndkdemo_MainActivity_stringFromJNI组成:类名_方法名组成。参数JNIEnv *和jobject必须有,JNIEnv之jvm指针,jobject指调用该函数的java类引用。

在jni目录下新建jnitest.c文件,刚才com_example_lynnlee_ndkdemo_MainActivity.h名字太长,改为jnitest.h。

//
// Created by LynnLee on 2018/8/5.
//
#include "jnitest.h"

JNIEXPORT jstring JNICALL Java_com_example_lynnlee_ndkdemo_MainActivity_stringFromJNI(JNIEnv *env, jobject obj)
{
    return (*env)->NewStringUTF(env, "LynnLee");
}

函数实现就返回了一个"LynnLee"字符串

在jni目录下新建Android.mk文件,Android.mk文件是Android 的makefile文件

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := jnitest.c
include $(BUILD_SHARED_LIBRARY)

宏函数’my-dir’由编译系统提供,返回当前包含Android.mk文件的目录路径

CLEAR_VARS由编译系统提供,清除除LOCAL_PATH以外的其它LOCAL_XXX变量

编译的目标对象,LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。
注意:编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为native-lib的共享库模块,将会生成'libnative-lib.so'文件。

include $(BUILD_SHARED_LIBRARY)

指定编译出的库类型1.BUILD_SHARED_LIBRARY:动态库;2.BUILD_STATIC_LIBRARY:静态库;3.BUILD_EXECUTEABLE指:可执行文件

Application.mk

APP_ABI := all

APP_ABI有四种类型(默认armeabi),armeabi、armeabi-v7a、x86、mips,设置时以空格隔开,all表示所有。

生成库

需要修改app/CMakeLists.txt文件,修改如下:


CMakeLists.txt.png

利用上篇创建的ndk -build命令工具生成库


so库.png

使用库

sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
/*externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }*/

否则报错:


错误.png

gradle修改如下图


gradle.png 运行效果.png

git代码路径:https://github.com/lynnleescz/NDKdemo

上一篇下一篇

猜你喜欢

热点阅读