{ ndk }

  • 任务2:简单手势识别

    |

    金老师给我们本周的任务是做一个手势识别?!

    好吧,我真的对此感到疑惑。到底什么程度才算是“手势识别”?

    在这个项目上花费了将近两周。
    遇到瓶颈时,我便开始怀疑自己是否在这个无底的项目上挥霍了并不充裕的时间。
    直到项目完成的前一刻,我仍禁不住思考这个项目的究竟有何意义。
    不过,好在最终成品里没有一行多余的代码。

    运行屏幕截图

    源码可见于Gitee

    虽然金老师的原话要求使用“Accelerometer和Gyroscope”,我的项目上只用了Accelerometer;
    我觉得我的思路不需要也无法使用到Gyroscope,即使有,也该是用RotationVectorSensor。

  • 任务1.1:编译SensorGraph

    |

    金老师给我们本周的任务编译Android NDK示例中的SensorGraph。如果已经做过任务1的话,这个任务应该会很简单。

    从Github上clone源代码,将SensorGraph项目导入Android Studio,Gradle Sync & Build即可。

    运行屏幕截图
  • 任务1:Android与交叉编译

    |

    金老师这周给我们布置的任务是:“交叉编译一个共享库(Shared Object),在安卓手机中加载它,显示一个Hello, world。”

    要实现这一个目标有很多种途径,最简单的应该算是使用Android Studio中集成好的NDK。Android开发基本上离不开Android Studio。

    NDK是额外组件,需要通过Android Studio中的SDK Manager进行安装。安装时还可以勾选构建工具CMake和调试用的LLDB。

    安装完所有需要的组件后就万事俱备了。凭空将C++引入Android开发,最简单的方法就是从Native C++模板新建Android项目。

    不过,从Native C++模板新建的项目有可能会默认选择其他NDK版本而拒绝使用当前的安装的NDK。这时,在模块的build.gradle配置文件中将NDK的版本指定为当前安装的版本即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    apply plugin: 'com.android.application'

    android {
    compileSdkVersion 28
    defaultConfig {
    // ...
    }

    buildTypes {
    // ...
    }

    // 在这里指定NDK版本。
    ndkVersion "21.0.6113669"

    externalNativeBuild {
    cmake {
    path "src/main/cpp/CMakeLists.txt"
    version "3.10.2"
    }
    }
    }

    dependencies {
    // ...
    }

    模板已经将Gradle所需的全部依赖完整配置好了,并自动在MainActivity中引用了一个native String stringFromJNI()方法。直接修改这个方法的实现就算是完成任务了。

    这里也可以再多做一层封装:

    在Project视图下的app/cpp里新建先定义C++头文件hello.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef HI_NDK_HELLO_H
    #define HI_NDK_HELLO_H

    #include <string>
    using std::string;

    /**
    * 用英语和中文说“世界你好。”
    * @return "Hello, world! 世界你好!"
    */
    string sayHi();

    #endif //HI_NDK_HELLO_H

    编写对应的C++实现文件hello.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include "hello.h"
    #include <android/log.h>
    using namespace std;

    /**
    * 用英语和中文说世界你好,以期检验JNI中的编码问题。
    * @return "Hello, world! 世界你好!"
    */
    string sayHi() {
    string greeting = string("Hello, world! 世界你好!");

    // 在Logcat中可以看到输出。
    __android_log_write(android_LogPriority::ANDROID_LOG_INFO, "Hi", greeting.c_str());
    return greeting;
    }

    并将上述.cpp文件加入CMakeLists.txtadd_library处理器中,跟模板生成的native-lib.cpp放在一起。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # CMakeLists.txt
    # ...

    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).
    native-lib.cpp hello.cpp )

    最后在native-lib.cpp中调用新建的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include "hello.h"
    #include <jni.h>
    #include <string>

    extern "C"
    JNIEXPORT jstring JNICALL
    Java_net_qfstudio_hindk_MainActivity_getGreeting(JNIEnv *env, jobject thiz) {
    return env->NewStringUTF(sayHi().c_str());
    }

    执行Gradle Build并连接手机或模拟器运行,即可在Logcat和MainActivity屏幕中看到预期的输出。

    运行屏幕截图

    完整代码可见于Gitee

© 2021 - lightyears1998
Powered by Hexo , Theme - Icalm