zoukankan      html  css  js  c++  java
  • Android -- Android下的NDK开发(一)

    1,NDK是什么?为什么要进行NDK开发?

        NDK:Native Development Kit。Android应用运行在Dalvik虚拟机中。NDK允许开发人员使用本地代码语言(例如C和C++)实现应用的部分功能。这样以代码重用的形式能够给某类应用提供方便,而且在某些情况下能提高运行速度。

      在实际开发中,那为什么要学习JNI,JNI会学习到比较底层的东西,java可以实现上层应用的开发,但是不能写底层驱动,有些android项目必须和底层硬件打交道,比如要精确快速的获取某种传感器的值,那么java是不能办到的,那怎么办,就通过JNI开发,通过c/c++完成底层驱动或者值得获取,然后将值传回到java层。同样java层也可以将数据传递给c/c++层,这样通过JNI完成数据的交互。常见的产品如蓝牙、运动手环等。

    2,NDK环境搭建

      在Android studio2.2之后就可以使用我们的Android开发工具来开发了

    • 安装NDK

      Tools->Android->SDK Manager->SDK Tools选中CMake和NDK,点击确认,软件会自动安装NDK。

    • 将NDK添加到Android Studio环境中

      配置环境变量,方便cmd中的操作,在环境变量Path添加ndk目录

      在cmd中检查是否安装成功,输入ndk-build,出现如下效果即

      ok,环境安装好了我们来创建项目,和我们创建Android工程类似,只不过我们要勾选“include c/c++”

      一路Next ,最后创建项目,创建项目之后我们坑定有些文件没有见过,首先看一下native-lib.cpp类

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

      什么?一脸懵逼!嗯,我现在也和你一样,不过我们查查网上的资料来看看里面的代表什么意思

    其中extern “C” 是表示可以供外部调用。 
    jstring是返回值,maxFromJNI是Java代码中定义的函数。(过会儿会写在MainActivity里,一般是Java_包名_使用地方的类名_方法名) 
    Java_com_qianmo_ndktest_MainActivity_这一段是调用这个函数的java类以及它所在的包。 
    JNIEnv* env 和 jobject object是啥我也不知道,很显然这俩必须要用,貌似第一个代表的是什么指针什么的,后面以object类型命名的猜测可能是对象吧(手动微笑)。 
    

      继续看我们Activity中调用

    public class MainActivity extends AppCompatActivity {
    
        // Used to load the 'native-lib' library on application startup.
        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());
    
        }
    
        /**
         * A native method that is implemented by the 'native-lib' native library,
         * which is packaged with this application.
         */
        public native String stringFromJNI();
    
    }
    

      我们继续看看让我们懵逼的几个不熟悉的方法

    //加载这个native-lib里的函数和东西
        static {
            System.loadLibrary("native-lib");
        }
    //这就是对应的c++文件中的方法了
    public native String stringFromJNI();
    

      CMakeLists.txt,等等,这怎么生成了一个txt文件呢?,我们看一看里面的内容

    # For more information about using CMake with Android Studio, read the
    # documentation: https://d.android.com/studio/projects/add-native-code.html
    
    # Sets the minimum version of CMake required to build the native library.
    
    cmake_minimum_required(VERSION 3.4.1)
    
    # Creates and names a library, sets it as either STATIC
    # or SHARED, and provides the relative paths to its source code.
    # You can define multiple libraries, and CMake builds them for you.
    # Gradle automatically packages shared libraries with your APK.
    
    add_library( # Sets the name of the library.
                 native-lib
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                 src/main/cpp/native-lib.cpp )
    
    # Searches for a specified prebuilt library and stores the path as a
    # variable. Because CMake includes system libraries in the search path by
    # default, you only need to specify the name of the public NDK library
    # you want to add. CMake verifies that the library exists before
    # completing its build.
    
    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 )
    
    # Specifies libraries CMake should link to your target library. You
    # can link multiple libraries, such as libraries you define in this
    # build script, prebuilt third-party libraries, or system libraries.
    
    target_link_libraries( # Specifies the target library.
                           native-lib
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    

      继续懵逼,不过我们有搜索引擎,来看看里面的一些语句到底代表什么

    # 指定cmake最低版本,如果不知道就复制吧
    cmake_minimum_required(VERSION 3.4.1)
    
    # 第一个native-lib是供java调用的文件, SHARED 表示将代码编译成动态库即so库,相对 的还有一个STATIC表示静态
    # 最后俩是所有cpp的名字和相对本文件的位置,这里在一个文件夹中就直接写名字了,文件有多少写多少
    add_library(native-lib SHARED native-lib.cpp Max.cpp)
    
    # 我的理解是java要连接到native-lib,和一些其它的东西
    target_link_libraries(native-lib)
    

      OK,上面把基本的一些意思读懂了,那么我们就依葫芦画瓢,仿照着写一个试试呗,首先创建NDKUtils.java类,添加c++方法getStringFromC,添加hello-jin.cpp文件导入,代码如下:

    public class NDKUtils {
    
        static {
            System.loadLibrary("hello-jni");//导入生成的链接库文件
        }
    
        public staticnative String getStringFromC();
    
    
    }
    

      继续我们创建hello-jin.cpp文件,并创建 getStringFromC()方法,代码如下:

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_qianmo_ndktest_NDKUtils_getStringFromC(
            JNIEnv *env,
            jobject /* this */) {
        std::string hello = "这里是来自与c++";
        return env->NewStringUTF(hello.c_str());
    }
    

      在CMakeLists.txt文件中添加java和c++文件的链接

    add_library(hello-jni SHARED src/main/cpp/hello-jni.cpp)
    
    target_link_libraries(hello-jni)
    

      ok,这样我们就写完了,看一下我们运行的效果

      OK,今天就给大家分享简单的NDK环境搭建和简单的数据获取,由于我自己也不怎么会写c/c++文件(都忘光了),所以后面我边学习边给大家继续分享NDK开发知识(有好的NDK开发知识的同学求共享呀,谢了啊)

  • 相关阅读:
    动态生成java、动态编译、动态加载
    boostrap标签
    Java后端WebSocket的Tomcat实现
    编程过程与规范
    敏捷开发过程
    软件过程模型
    软件过程
    ISO9126 质量模型
    手机淘宝架构演化实践
    蒋勋:知识分子应具备怎样的美学修养
  • 原文地址:https://www.cnblogs.com/wjtaigwh/p/6728813.html
Copyright © 2011-2022 走看看