• android 串口开发第一篇:搭建ndk开发环境以及第一个jni调用程序


    一:ndk环境搭建

         1:开发环境

      我使用的是android studio 2.3.3版本,搭建ndk开发环境比较简单,打开File----Settings----Appearance&Behavior----System  Settings----Android SDK,选择SDK Tools,将CMake,LLDB,NDK 前的复选框勾上,点击Apply,然后就是等待ndk下载完成。

      安装成功后,右键项目----open  module setting,Android NDK location会自动赋值

      

     二:第一个jni程序

         1:创建ndk项目

          创建ndk项目和普通android项目有一点区别,需要把Include C++ support前面的复选框勾上,然后直接下一步。但在最后一步,有一个c++下拉框选项,可以根据你的实际情况适当修改,C++ Standard :点击下拉框,可以选择标准 C++,或者选择默认 CMake 设置的 Toolchain Default 选项。Exceptions Support :如果你想使用有关 C++ 异常处理的支持,就勾选它。勾选之后,Android Studio 会在 module 层的 build.gradle 文件中的 cppFlags 中添加 -fexcetions 标志。Runtime Type Information Support :如果你想支持 RTTI,那么就勾选它。勾选之后,Android Studio 会在 module 层的 build.gradle 文件中的 cppFlags 中添加 -frtti 标志。

                                                              

         项目创建好后,app下多了一个cpp目录,该目录用于存放c程序的源码,头文件,预编译项目等,android studio 会默认帮我们创建一个native-lib.cpp文件,该文件已有一个测试方法,结构图如下:

      

          通过上图看到,在External Build Files 下面多了一个CMakeLists.txt文件,该文件用于c程序需要生成so文件的配置文件。

      cmake_minimum_required(VERSION 3.4.1):这是版本信息,我们不用管它

      add_library():这个命令是,通过add.library()定义多个库,CMake会去自动构建他们,一个*.cpp文件对应一个add_library命令.

    add_library( # Sets the name of the library.生成so文件的名字,建议和cpp文件同名
                 native-lib
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s). 需要生成so文件的cpp文件名称
                 src/main/cpp/native-lib.cpp )

      find_library():定位 NDK library 的位置,并将其位置存储在一个变量之中。在构建脚本的其他地方使用这个变量,来代指 NDK library。下面的示例代码将 Android-specific log support library 的位置存储到变量 log-lib 中

    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 )

      现在我们来看native-lib.cpp文件,这是as帮我们自动生成好的,返回是一个Hello from C++的字符串。

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI(
            JNIEnv* env,
            jobject      /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
        JNIEXPORT jstring JNICALL 这里的jstring代表返回值, 参数JNIEnv* env,代表指针,jobject 代表调用这个方法的对像(普通方法是jobject,静态方法是jclass)后面的参数和java类中定义的本地方法对数相对应,方法命名规则:Java_包名_调用jni方法的类名_方法名,android studio 帮我们
    生成的程序,activity包名是serialport.com.ndkjnidemo,类名是MainActivity,方法名是stringFromJNI,所以native-lib.cpp方法名称为:Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI,其中返回值类型和java数据类型对应如下

        如果我们需要写多个jni方法,*.cpp格式如下:

    //方法一
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_serialport_com_ndkjnidemo_MainActivity_test1(
            JNIEnv* env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    //方法二
    
    extern "C"//如果不写extern "C"  java是无法调用到这里定义的方法
    JNIEXPORT jstring JNICALL
    Java_serialport_com_ndkjnidemo_MainActivity_test2(
            JNIEnv* env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }

      最后我们来看自动生成的MainActivity,在onCreate中调用stringFromJNI,然后给文本组件赋值,软件运行参见图一

    package serialport.com.ndkjnidemo;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.TextView;
    public class MainActivity extends AppCompatActivity {

    static
    {
        //native-lib值来自,CMakeLists.txt文件中,add_library命令的第一个参数 System.loadLibrary(
    "native-lib"); }
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView tv = (TextView) findViewById(R.id.sample_text);
    tv.setText(stringFromJNI());
    }

    public native String stringFromJNI();
    }

    代码都是android studio自动自成的,所以此处不上传代码,demo运行结果:  

     

    参考文章:

    Android NDK 开发(五)AndroidStudio 2.2 NDK的开发环境搭建

    一天掌握Android JNI本地编程 快速入门

      

  • 相关阅读:
    C++操作文件行(读取,删除,修改指定行)
    Windows注册表中修改UAC(用户账号控制)及批处理脚本
    Centos7.x 安装libevent2.x
    【Docker】:使用docker安装redis,挂载外部配置和数据
    【Docker】:使用docker安装mysql,挂载外部配置和数据
    开源定时任务框架Quartz(二)
    开源定时任务框架Quartz(一)
    Spring Boot系列教程十四:Spring boot同时支持HTTP和HTTPS
    数据结构与算法:单向链表实现与封装(有头)
    【C++札记】指针函数与函数指针
  • 原文地址:https://www.cnblogs.com/cq-jiang/p/8145281.html
Copyright © 2020-2023  润新知