IT全栈圈

Android NDK初探

2019-07-03  本文已影响8人  渝聆墨

什么是NDK?

NDK 是 Native Development Kit 的缩写,是 Android 的工具开发包。它的作用是快速开发 C/C++ 的动态库,并自动将动态库与应用一起打包到 apk。NDK 是属于 Android 的,与 Java 无直接关系。NDK 是 Android 中实现 JNI 的手段。那么什么是JNI呢?

什么是JNI

JNI 是 Java Native Interface 的缩写,即 Java 的本地接口,是java与c语言等其他语言通信的桥梁。目的是使得 Java 与 C/C++进行交互。

开始实战

1.新建native方法

package com.sunql.ndkfrist;
public class JniLoader {
    static {
        System.loadLibrary("demo-lib");
    }
    public native String stringFromJNI();

    public native String logFormJni();
}

2.创建jni目录,生成jni文件,生成文件代码如下
3.javah
-jni 生成进头文件
-d 输出目录
-classpath <path> 加载引用路径
命令:
(1)进入项目根目录
(2)找到sdk/platforms/android-16/android.jar
(3)javah -classpath bin/classes ;../sdk/platforms/android-16/android.jar -d jni packeageName.className 生成jni文件目录
javah -d jni -classpath F:\Android\Sdk\platforms\android-28\android.jar;....\build\intermediates\classes\debug com.sunql.ndkfrist.J
NITest
4.创建实体类.c 文件 ,引入生成的jni头文件。

#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_sunql_ndkfrist_JniLoader_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

5.引入Android.mk文件 ,加入编译的文件配置。
build.gradle配置详情展示:

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.sunql.ndkfrist"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                // 默认是 “ cppFlags "" ”
                // 如果要修改 Customize C++ Support 部分,可在这里加入
                cppFlags "-frtti -fexceptions"
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
    sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }
}

CMakeLists.txt配置文件如下:

cmake_minimum_required(VERSION 3.4.1)

add_library(demo-lib
             SHARED
             src/main/cpp/demo-lib.cpp )
add_library(test-demo
             SHARED
             src/main/cpp/test-demo.cpp )

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

target_link_libraries(demo-lib
                       ${log-lib} )
target_link_libraries(test-demo
                       ${log-lib} )

6.根目录命令:ndk-build命令生成.so文件。使用android studio开发生成的.so文件会直接在build目录下的intermediates\cmake\debug\obj\arm64-v8a目录中。复制.so文件到其他项目的lib中就可以调用.so中的API方法了。


image.png

7.初始化jni类,调用完成。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        JniLoader jniLoader=new JniLoader();
        String string=  jniLoader.stringFromJNI();
        TextView textView=findViewById(R.id.textview);
        if (!TextUtils.isEmpty(string)){
            textView.setText(string);
        }else {
            textView.setText("获取null");
        }
    }
}

项目代码:

https://github.com/sunql0827/NdkFrist

上一篇下一篇

猜你喜欢

热点阅读