Android NDK 开发

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011608180/article/details/85063634

1.什么是Android NDK?

The Android NDK is a toolset that lets you implement parts of your app in native code, using languages such as C and C++. For certain types of apps, this can help you reuse code libraries written in those languages.

Android NDK是一个工具集,可让您使用C和C ++等语言以本机代码实现应用程序的各个部分。对于某些类型的应用程序,这可以帮助您重用以这些语言编写的代码库。

2.Android NDK 适用的场景:

  • 在平台之间移植他们的应用
  • 从设备中挤出额外的性能以实现低延迟或运行计算密集型应用程序,例如游戏或物理模拟。
  • 重用您自己或其他开发人员的C或C ++库。

3.什么是JNI?

The JNI is a native programming interface. It allows Java code that runs inside a Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages, such as C, C++, and assembly.

JNI是本机编程接口。它允许在Java虚拟机(VM)内运行的Java代码与使用其他编程语言(如C,C ++和汇编语言)编写的应用程序和库进行互操作。

The most important benefit of the JNI is that it imposes no restrictions on the implementation of the underlying Java VM. Therefore, Java VM vendors can add support for the JNI without affecting other parts of the VM. Programmers can write one version of a native application or library and expect it to work with all Java VMs supporting the JNI.

JNI最重要的好处是它对底层Java VM的实现没有任何限制。因此,Java VM供应商可以添加对JNI的支持,而不会影响VM的其他部分。程序员可以编写一个版本的本机应用程序或库,并期望它可以与支持JNI的所有Java VM一起使用。

4.在Android Studio 中如何使用(NDK-Build)?

一.创建一个新的Android 工程,如下图:

二.新建class文件,并创建native接口。(红颜色错误不用关心),点击菜单栏“build”,选择“Make Project”,生成class文件。

三. 生成.h头文件

在debug文件上,点击右键并选择Copy Path,在Terminal端输入:

cd /home/tony/work/git/git/HelloJNI/app/build/intermediates/classes/debug

使用javah生成头文件 (前提:ubuntu java 环境配置OK)

javah -d ../../../../src/main/jni/ -jni com.abilix.hello.jni.HelloJNI

生成成功以后会在app/src/main/路径中多一个jni的文件夹和生成的.h文件,如图:

四. 头文件生成以后,可以在jni目录中创建一个测试的cpp文件hello.cpp,步骤: “ 右键jni文件夹 -> New -> C/C++ Source File” ,填写cpp的名称hello.

五:引入jni头文件,编写cpp代码

 六:添加 Android.mkApplication.mk 两个文件

Android.mk 

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello_lib
LOCAL_SRC_FILES := hello.cpp

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions -std=c++11
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-19

七:使用ndk-build编译

  ctrl + alt + t 打开 Terminal,cd到jni目录

cd /home/tony/work/git/git/HelloJNI/app/src/main/jni

  然后ndk-build (此步骤应该先保证ndk配置成功,参考 ubuntu android ndk环境配置

tony@tomy-pc:~/work/git/git/HelloJNI/app/src/main/jni$ ndk-build
Android NDK: WARNING: APP_PLATFORM android-19 is higher than android:minSdkVersion 1 in /home/tony/work/git/git/HelloJNI/app/src/main/AndroidManifest.xml. NDK binaries will *not* be comptible with devices older than android-19. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information.    
/home/tony/Android/Sdk/ndk-bundle/build/core/setup-app.mk:81: Android NDK: Application targets deprecated ABI(s): armeabi    
/home/tony/Android/Sdk/ndk-bundle/build/core/setup-app.mk:82: Android NDK: Support for these ABIs will be removed in a future NDK release.    
[armeabi] Compile++ thumb: vision_lib <= hello.cpp
[armeabi] SharedLibrary  : libvision_lib.so
[armeabi] Install        : libvision_lib.so => libs/armeabi/libvision_lib.so
[armeabi-v7a] Compile++ thumb: vision_lib <= hello.cpp
[armeabi-v7a] SharedLibrary  : libvision_lib.so
[armeabi-v7a] Install        : libvision_lib.so => libs/armeabi-v7a/libvision_lib.so

 八:在HelloJNI代码中加载so库

static {
  System.loadLibrary("hello_lib");
}

九:在build.gradle的android节点中加入如下代码

  sourceSets {
    main {
      jniLibs.srcDir 'src/main/libs'
      jni.srcDirs = []
    }
  }

十:在MainActivity中进行测试,看Log是否正常打印出来。

更新:2018/12/20 (在cpp中使用Log)

如何在cpp代码中使用Log打印??在Android.mk中添加如下代码

LOCAL_LDLIBS    += -llog

最终的Android.mk代码如下所示:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello_lib
LOCAL_SRC_FILES := hello.cpp

LOCAL_LDLIBS    += -llog

include $(BUILD_SHARED_LIBRARY)

cpp代码中使用与测试:

#include "com_abilix_hello_jni_HelloJNI.h"

#include <android/log.h>
#define LOG_TAG "wer_vision_lib"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

JNIEXPORT jstring JNICALL Java_com_abilix_hello_jni_HelloJNI_getStrFromJNI
  (JNIEnv *env, jobject)
{
  LOGE("This is JNI Log");
  return env->NewStringUTF("Hello from JNI");
}

Logcat打印输出:

01-02 14:42:36.933 4040-4040/com.abilix.hello.jni E/wer_vision_lib: This is JNI Log
01-02 14:42:36.933 4040-4040/com.abilix.hello.jni E/tony: Hello from JNI

猜你喜欢

转载自blog.csdn.net/u011608180/article/details/85063634