Android NDK初探

作者: 渝聆墨 | 来源:发表于2019-07-03 23:29 被阅读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

    相关文章

      网友评论

        本文标题:Android NDK初探

        本文链接:https://www.haomeiwen.com/subject/vkqmzftx.html